第9章 Python笔记 魔法方法、属性和迭代器

xiaoxiao2021-02-28  85

一、构造方法

构造方法和其他普通方法不同之处在于,当一个对象被创建后,会立即调用构造方法。创建构造方法时只需要吧init方法修改为__init__即可:

class Foobar: def __init__(self): self.somevar=42 >>> f=Foobar() >>> f.somevar 42注意:在Python中__del__方法,也就是析构方法。它在对象就要被垃圾回收之前调用。但是发生的具体时间是不可知的,所以少用该方法。

1、重写一般方法和特殊的构造方法

如果一个方法在B类的一个实例中被调用(或者一个属性被访问)但在B类中没有找到该方法,那么就会去它的超类A里面找。

class A: def hello(self): print "Hello,I'm A." class B(A): pass >>> a=A() >>> b=B() >>> a.hello() Hello,I'm A. >>> b.hello() Hello,I'm A.如果一个类的构造方法被重写,那么就需要调用超类的构造方法,否则对象可能不能正确初始化:

class Bird: def __init__(self): self.hungry=True def eat(self): if self.hungry: print 'Aaaah....' self.hungry=False else: print 'No,thanks!' class SongBird(Bird): def __init__(self): self.sound='Squawk!' def sing(self): print self.sound >>> sb=SongBird() >>> sb.sing() Squawk! >>> sb.eat() Traceback (most recent call last): File "<pyshell#16>", line 1, in <module> sb.eat() File "C:/Users/Administrator.USER-20170615PK/Desktop/9/6.py", line 5, in eat if self.hungry: AttributeError: SongBird instance has no attribute 'hungry'由上述代码可以看出,SongBird是bird的一个子类,它继承了eat方法,但是在调用eat方法时出现了错误。有以下两种解决方案:

1.1 调用未绑定的超类构造方法

class Bird: def __init__(self): self.hungry=True def eat(self): if self.hungry: print 'Aaaah....' self.hungry=False else: print 'No,thanks!' class SongBird(Bird): def __init__(self): Bird.__init__(self) self.sound='Squawk!' def sing(self): print self.sound >>> sb=SongBird() >>> sb.sing() Squawk! >>> sb.eat() Aaaah.... >>> sb.eat() No,thanks!在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上,这被称为绑定方法。但是如果直接调用类的方法(比如Bird.__init__)那么就没有实例会被绑定。这样就可以自由地提供需要的self参数。这样的方法称为未绑定方法。

1.2 使用super函数

super函数只能在新式类中使用。当前的类和对象可以作为super函数的参数使用,调用函数返回的对象的任何方法都是调用超类的方法,而不是当前类的方法。

__metaclass__=type#super函数只在新式类中起作用 class Bird: def __init__(self): self.hungry=True def eat(self): if self.hungry: print 'Aaaah....' self.hungry=False else: print 'No,thanks!' class SongBird(Bird): def __init__(self): super(SongBird,self).__init__() self.sound='Squawk!' def sing(self): print self.sound 二、成员访问

创建自己的序列或者映射需要实现所有的序列或者映射规则的方法,包括__getitem__和__setitem__这样的的特殊方法。通过子类化list(或UserList)和dict(或者UserDict)能节省很多工作。

__len__(self):该方法返回集合中所含项目的数量。

__getitem__(self,key):这个方法返回与所给键对应的值。

__setitem__(self,key,value):该方法应该按一定的方式存储和key相关的value。

__delitem__(self,key):该方法对一部分对象使用del语句时被调用,同时必须删除和键相关的键。 三、属性

1、property函数

class Rectangle: def __init__(self): self.width=0 self.height=0 def setSize(self,size): self.width,self.height=size def getSize(self): return self.width,self.height >>> r=Rectangle() >>> r.width=10 >>> r.height=5 >>> r.getSize() (10, 5) >>> r.setSize((150,100)) >>> r.width 150使用property函数:

__metaclass__=type class Rectangle: def __init__(self): self.width=0 self.height=0 def setSize(self,size): self.width,self.height=size def getSize(self): return self.width,self.height size=property(getSize,setSize) >>> r=Rectangle() >>> r.width=10 >>> r.height=5 >>> r.size (10, 5) >>> r.size=150,100 >>> r.width 150property函数创建了一个属性,其中访问器函数被用作参数(先是取值,然后是赋值),这个属性名为size。 2、静态方法和类成员方法

静态方法和类成员方法在创建时分别被装入staticmethod类型和classmethod类型的对象中。静态方法的定义没有self参数,且能够被类本身直接调用。类方法在定义时需要名为cls的类似于self的参数,类成员方法可以直接用类的具体对象调用。但cls参数是自动被绑定到类的。

使用@操作符,在方法(或函数)的上方将装饰器列出,从而指定一个或者更多的装饰器(多个装饰器在应用时的顺序与指定顺序相反)。

__metaclass__=type class MyClass: @staticmethod def smeth(): print 'This is a static method' @classmethod def cmeth(cls): print 'This is a class method of ',cls 3、__getattr__、__setattr__和它的朋友们

__getattribute__(self,name):当特性name被访问时自动被调用(只能在新式类中使用)。

__getattr__(self,name):当特性name被访问且对象没有相应的特性是被自动调用。

__setattr__(self,name,value):当试图给特性name赋值时会被自动调用。

__delattr__(self,name):当试图删除特性name时被自动调用。

四、迭代器

只要该对象实现了__iter__方法,就可以对该对象进行迭代。

__iter__方法会返回一个迭代器,所谓的迭代器就是具有next方法(这个方法在调用时不需要任何参数)的对象。在调用next方法时,迭代器会返回它的下一个值。如果next方法被调用,但迭代器没有值可以返回,就会引发一个StopIteration异常。

正式的说法是,一个实现了__iter__方法的对象是可迭代的,一个实现了next方法的对象则是迭代器。

class Fibs: def __init__(self): self.a=0 self.b=1 def next(self): self.a,self.b=self.b,self.a+self.b return self.a def __iter__(self): return self 五、生成器

nested=[[1,2],[3,4],[5]] def flatten(nested): for sublist in nested: for element in sublist: yield element 任何包含yield语句的函数称为生成器。它不像return那样返回值,而是每次产生多个值。每次产生一个值(使用yield语句),函数就会被冻结:即函数停在那点等待被重新唤醒。函数被唤醒后就从停止的那点开始知行。 本章新函数:

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

最新回复(0)