魔法方法、属性和迭代器

魔法方法、属性和迭代器

2015年8月9日

21:29

 

__'   '————(这种拼写表示名字有特殊含义)

  在python中,由这些名字组成的集合所包含的方法称为魔法方法。若对象实现了这些方法中的某一个,那么 这个方法会在特殊情况下(确切地说是根据名字被python调用,而几乎没有直接调用他们的必要)。

 

构造方法:是一个与类同名且没有返回值类型的方法。对象的创建就是通过构造函数来完成的,其主要功能是完成对象的初始化。

 

python中创建构造方法,把init方法修改为__init__

Class BO:

     def __init__ (self):

                self.somevar=42

                  f=BO()

                 f.somevar

 

 

若给构造方法传递几个参数会发生何种情况?

  在python中,__init__是使用最多的一个。

 

 

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

   当处理构造方法与重写普通方法时,遇到的问题 :若一个类的构造方法被重写,那么需要调用超类的构造方法。

 

 

如何达到该目的:

1、调用超类构造方法的未绑定版本。

2、使用super函数。

 

超类.__init__(self)  在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(这称为绑定)

 

但如果直接调用类的方法例如 超类.__init__,那么就没有实例被绑定。这样就可以自由地提供所需要的self参数,这样的方法称为未绑定方法。

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   

 

 

 

 

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

 

使用super函数的格式

  super(子类,self).__init__() super 函数实际访问的是所需的超类,它返回了一个super对象,这个对象负责进行方法解析。

__metaclass__ = type
class Bird:
    def __init__(self):
        self.hungry = True  此处的hungry实际上是属性
    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   

 

 

 

 

成员访问:

1、规则:管理某种形式的行为的规则,它说明了应该事先何种方法和这些方法应该做什么。

 

序列和映射是对象的集合。为实现其基本的行为(规则),若对象不可变,那么需要使用2个魔法方法,若是可变的,则需要使用4个。

 

__len__(self): 返回集合中所含项目的数量。若是序列,则这就是元素的个数。 若是映射,则返回的是键-值对的数量。若__len__返回0,对象会当前一个bool变量中的假值所代替。

 

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

 

 

__setitem__(self,key):该方法应该按一定的方式存储和key相关的value,该值随后可用__getitem__来获取。

 

__delitem__(self,key):对部分对象使用del语句时被调用,同时必须删除和元素相关的键。

 

附加要求:对一个序列来说,若键是整数,那么要从末尾开始计数。换句话讲就是x[-n]和x[len(x)-n]是一样的。

 

 

 

属性:访问器方法。访问器是一个简单的方法,他能够使用setsize,getsize()这样的名字来得到或者重绑定一些特征。如果在访问给定的特性时必须要采取一些行动,类似于这样的封装状态就十分重要。

python中有两种创建属性的机制,只在新式类中使用property函数。

 

 size=property(getsize,setsize) 先在类中所定义的函数。

r.size 调用函数。

 

静态方法和类成员方法

 

Python的静态方法和类成员方法都可以被类或实例访问,两者概念不容易理清,但还是有区别的:

1)静态方法无需传入self参数,类成员方法需传入代表本类的cls参数;

2)从第1条,静态方法是无法访问实例变量的,而类成员方法也同样无法访问实例变量,但可以访问类变量;

3)静态方法有点像函数工具库的作用,而类成员方法则更接近类似Java面向对象概念中的静态方法。

 

例子如下(注意print里的说明):

class MyClass:

    val1 = 'Value 1'

    def __init__(self):

        self.val2 = 'Value 2'

    def staticmd():

        print '静态方法,无法访问val1和val2'

    smd = staticmethod(staticmd)

 

    def classmd(cls):

        print '类方法,类:' + str(cls) + ',val1:' + cls.val1 + ',无法访问val2的值'

    cmd = classmethod(classmd)

 

 

 

1、静态方法:创建时被装入staticmethod类型。静态方法的定义没有self参数,且能够被类本身直接调用。

2、类成员方法:创建时被装入classmethod类型。 类成员方法可以直接用类的具体对象来调用,但cls参数是自动被绑定到类的。

 

Smeth=staticmethod(函数)

Cmeth=classmethod(函数)

 

 

在包中引入了一个叫做装饰器的新语法。

 装饰器:能够对任何可调用对象进行包装,即能够使用方法,也能够运用函数。

 

使用@操作符,在方法(或函数)的上方将装饰器列出,从而指定一个或多个装饰器。

 

 

importtime 

    

deftimeit(func): 

    defwrapper(): 

        start =time.clock() 

        func() 

        end =time.clock() 

        print'used:', end -start 

    returnwrapper 

   

@timeit 

deffoo(): 

    print'in foo()' 

    

foo()

装饰器的实例

使用timeit来装饰foo这个函数。

 

多个装饰器在应用时的顺序与指定顺序相反。

class MyClass:

    val1 = 'Value 1'

    def __init__(self):

        self.val2 = 'Value 2'

 

    @staticmethod

    def staticmd():

        print '静态方法,无法访问val1和val2'

 

    @classmethod

    def classmd(cls):

        print '类方法,类:' + str(cls) + ',val1:' + cls.val1 + ',无法访问val2的值'

 

 

计算机生成了可选文字:
metaclass 
type 
class Rectangle: 
def init (self): 
self.width 0 
self.height 0 
def setSize(se1f, size): 
self.width. self.height size 
def getSize(se1f) : 
return self.width, self. height 
size - property(getSize. setSize)

 

如果上述执行过程太复杂,记住以下两点就好了:

1. 静态成员方法: 不能访问类属性,实例属性,相当于一个独立的方法,可以理解和类没关系,只是用类加了个作用域,比如:一个类,有三种加密算法,可以考虑静态方法;

2. 类成员方法   : 能访问类属性,无法访问实例属性,这里要注意,python是动态语言,和c++不同,实例是可以动态添加属性的,即实例的属性和类的属性不一定一样。

 

__getattr__、__setattr__以及其他类似拦截对象的所有特性访问是可能的,这样可用旧式类实现属性。

 

为了在访问特性的时候可执行代码,必须使用一些魔法方法。

 

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

 

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

 

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

 

   def __setattr__(self,name,value):

      if name =='size'

Self.width , self.height = value

 

 

 

 

 

posted @ 2017-09-12 16:12  xiaogao2700c  阅读(210)  评论(0编辑  收藏  举报