python的魔法方法

xiaoxiao2021-02-28  88

1.构造和析构 -魔法方法总是 被双下划线包围 -魔法方法是面向对象的Python的一切,如果你不知道魔法方法,说明你还没能意识到面向对象的Python的强大 -他们总能在适当的时候被 自动调用 __init__(self[,...]) 类在实例化对象的时候,就会自动调用的方法 返回值是none, 但是却不是实例化时调用的第一个方法 __new__(cls[,...])实例化时,调用的第一个方法 我们大多数时候不会重写它 因为str是不可改变的类型 >>> class CapStr(str): def __new__(cls,string): string = string.upper() return str.__new__(cls,string) >>> a=CapStr("i love yOU") >>> a 'I LOVE YOU' __del__(self) 析构器 垃圾回收机制自动调用这个方法  2.python会更灵活 >>> class int(int): def __add__(self,o): return int.__sub__(self,o) >>> a = 5 >>> b= 3 >>> a+b 8 >>> a = int("5") >>> b = int(3) >>> a + b 2 3.反运算 a + b 当a对+ 不支持时,就会调用b的+的反运算 >>> class Nint(int): def __radd__(self,o): return int.__sub__(self,o) >>> a = Nint(5) >>> b = Nint(3) >>> a+b 8 >>> 1+b  #3-1=2 2 4.简单定制(计时器) import time as t class MyTimeer(): def __init__(self): self.prompt = "no start..." self.lasted = [] self.startNum = 0 self.stopNum = 0 def __str__(self): return self.prompt __repr__ = __str__ def start(self): self.startNum=t.localtime() print("start...") def stop(self): self.stopNum= t.localtime() self.__calc() print("stop...") def __calc(self): self.lasted = [] self.prompt = "all time is" for index in range(6): self.lasted.append(self.stopNum[index]-self.startNum[index]) self.prompt += str(self.lasted[index]) t1 = MyTimeer() t1.start() for i in range(99999): print(" ") t1.stop() print(t1) 5.属性访问 >>> class C: def __init__(self): self.x = 'x-Man' >>> c = C() >>> c.x 'x-Man' >>> getattr(c,'x','没有') 'x-Man' >>> getattr(c,'y','no attribute') 'no attribute' 属性访问 的魔法方法 class Rectangle:     def __init__(self,width = 0,height = 0):         self.width =  width         self.height = height     def __setattr__(self, key, value):         if key == 'square':             self.width = value             self.height = value         else:             self.key = value     def getArea(self):         return self.width * self.height 以上会出现死循环。 修改一下(调用基类的__setattr__): class Rectangle: def __init__(self,width = 0,height = 0): self.width = width self.height = height def __setattr__(self, key, value): if key == 'square': self.width = value self.height = value else: super.__setattr__(key,value) def getArea(self): return self.width * self.height 或者 class Rectangle: def __init__(self,width=0,height=0): self.width = width self.height = height def __setattr__(self, name, value): if name == 'square': self.width = value self.height = value else: self.__dict__[name] = value def getArea(self): return self.width * self.height r1 = Rectangle(4,5) print(r1.getArea()) r1.square = 10 print(r1.width) print(r1.getArea()) 6.描述符:将某种特殊类型(要实现__get__,__set__,__del__三个中至少一个)的类的实例指派给另一个类的属性。 >>> class MyDecripptor: def __get__(self,instance,owner): print("getting",self,instance,owner) >>> class Test: x = MyDecripptor() >>> class Myproperty: def __init__(self,fget=None,fset=None,fdel=None): self.fget = fget self.fset = fset self.fdel = fdel def __get__(self,instance,owner): return self.fget(instance) def __set__(self,instance,value): return self.fset(instance,value) def __del__(self,instance): self.fdel(instance) >>> class C: def __init__(self): SyntaxError: invalid syntax >>> class C: def __init__(self): self._x = None def getX(self): return self._x def setX(self,value): self._x = value def delX(self): del self._x x= Myproperty(getX,setX,delX) >>> c = C() >>> c.x = "x-man" >>> c.x 'x-man' >>> c._x  7.定制容器 如果定制的容器是不可改变的话,你只需要定义__len__()和__getitem__()方法 如果定制的容器是可变的话,除了__len__()和__getitem__()方法,还需要定义___setitem__()和__delitem__()两个方法 不可改变的列表,统计访问次数 class CountList: def __init__(self,*arg): self.values = [x for x in arg] self.count = {}.fromkeys(range(len(self.values)),0) def __len__(self): return len(self.values) def __getitem__(self,key): self.count[key] += 1 return self.values[key] c1 = CountList(1,3,5,7,9) c2 = CountList(2,4,6,8,10) print(c1[1]) print(c2[1]) print(c1[1]+c2[1]) print(c1.count)

8.迭代

对字典进行迭代:

利用iter()和next()进行迭代

                        

9.生成器(也是一个迭代器的实现)

所谓协同程序就是可以运行独立函数调用,函数可以暂停或者挂起,并在需要的时候从程序离开的地方继续或者重新开始。

各种推导式:

转载请注明原文地址: https://www.6miu.com/read-80936.html

最新回复(0)