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

一、构造方法

构造方法和其他普通方法不同之处在于,当一个对象被创建后,会立即调用构造方法。创建构造方法时只需要吧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 "", line 1, in 
    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
150
property函数创建了一个属性,其中访问器函数被用作参数(先是取值,然后是赋值),这个属性名为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语句),函数就会被冻结:即函数停在那点等待被重新唤醒。函数被唤醒后就从停止的那点开始知行。

本章新函数:

第9章 Python笔记 魔法方法、属性和迭代器_第1张图片

你可能感兴趣的:(Python自学知识点总结)