python学习8 -魔法方法,属性

魔法方法:

  以 "__" 开头和结尾的名称,这些名字组成的集合叫做魔法方法,如 "__main__","__init__"

 

  构造方法:

    当一个对象被创建后,会立刻调用构造方法 ,在python 的所有魔法方法中 __init__ 是被调用最多的方法之一

 1 >>> class foobar():
 2     def init(self):
 3         pass
 4 
 5 >>> f = foobar()
 6 >>> f.init()
 7 
 8 等同于
 9 >>> class foobar():
10     def __init__(self):
11         pass
12 
13 >>> f = foobar()

   重写:

    如果一个类的构造方法被重写,那么就需要调用超类的构造方法,否则对象就不能正确的被初始化!

 1 class Bird:
 2     def __init__(self):
 3         self.hungry = True
 4 
 5     def eat(self):
 6         if self.hungry:
 7             print "Aaaaaa"
 8             self.hungry = False
 9         else:
10             print "No,Thanks"
11 
12 >>> b = Bird()
13 >>> b.eat()
14 Aaaaaa
15 >>> b.eat()
16 No,Thanks
 1 class SonBird(Bird):
 2     def __init__(self):
 3         self.sound = "Squawk"
 4 
 5     def sing(self):
 6         print self.sound
 7 
 8 >>> sb = SonBird()
 9 >>> sb.sing()
10 Squawk
11 >>> sb.eat()
12 
13 #如果调用父类的方法,则报错
14 Traceback (most recent call last):
15   File "<pyshell#6>", line 1, in <module>
16     sb.eat()
17   File "C:/Python27/overwrite.py", line 6, in eat
18     if self.hungry:
19 AttributeError: SonBird instance has no attribute 'hungry'

    造成 上面的原因是 因为构造方法被重写,新的构造方法没有任务初始化hungry 特性的代码,所以 SonBird 的构造方法必须调用父类Bird的构造方法来确保进行基本的初始化!示例代码如下:

 1 #1
 2 class SonBird(Bird):
 3     def __init__(self):
 4         Bird.__init__(self)    ------多了这行
 5         self.sound = "Squawk"
 6 
 7     def sing(self):
 8         print self.sound
 9 
10 #2
11 class SonBird(Bird):
12     def __init__(self):
13         super(SonBird,self).__init()   --多了这行
14         self.sound = "Squawk"
15 
16     def sing(self):
17         print self.sound

 

  基本的序列和映射规则

    序列和映射是对象的集合,只要使用下面定义的魔法方法,就能实现他们的基本规则(不可变对象,2个,可变,4个)

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

    __getitem__(self,key):返回所给键对应的值

    __setitem__(self,key,value):按一定的方式存储和KEY相关的value

    __delitem__(self,key):这个方法对一部分对象使用del 语句时被调用,同事必须删除和元素相关的key

示例如下

 1 def checkIndex(key):
 2     if not isinstance(key,int):raise TypeError
 3     if key <0 :raise IndexError
 4 
 5 class ArithmeticSequence:
 6     def __init__(self,start = 0,step = 1):
 7         self.start = start
 8         self.step = step
 9         self.changed = {}
10 
11     def __getitem__(self,key):
12         checkIndex(key)
13         try:
14             return self.changed[key]
15         except KeyError:
16             return self.start + key * self.step
17 
18     def __setitem__(self,key,value):
19         checkIndex(key)
20         self.changed[key] = value
21 
22 
23 >>> s = ArithmeticSequence(1,2)
24 >>> s[4]
25 9
26 >>> s[4] =2
27 >>> s[4]
28 2

  子类化列表,字典,字符串

    标准库中 有3个关于序列和映射规则的类可以作为父类,来创建序列和映射  UserList,UserString,UserDict

 

属性

   property 函数   --创建一个属性,其中访问器函数被用作参数(显示 取值,然后是赋值)

 1 __metaclass__ = type
 2 class Rectangle:
 3     def __init__(self):
 4         self.width = 0
 5         self.height = 0
 6         
 7     def setSize(self,size):
 8         print "set is pay"
 9         self.width,self.height = size
10 
11     def getSize(self):
12         return self.width,self.height
13 
14     def delSize(self):
15         del self.width,self.height
16 
17     size = property(getSize,setSize,delSize)
18 
19 
20 >>> r1 = Rectangle()
21 >>> r1.width = 10
22 >>> r1.height =20
23 >>> r1.size
24 (10, 20)
25 set is pay
26 >>> r1.width
27 100

 

  静态方法 和 成员方法

    静态方法 和 成员方法创建时分别被 装入StaticMethod 和 ClassMethod 类型的对象中,静态方法定义没有 self 参数,能够被类本身直接调用,类方法定义时需要名为 cls的类似于self 的参数,

类成员方法可以直接用类的的具体对象调用,示例代码如下:

 1 class TestClassMethod(object):
 2 
 3     METHOD = 'method hoho'
 4 
 5     def __init__(self):
 6         self.name = 'leon'
 7 
 8     def test1(self):
 9         print 'test1'
10         print self
11 
12     @classmethod
13     def test2(cls):
14         print cls
15         print 'test2'
16         print TestClassMethod.METHOD
17         print '----------------'
18 
19     @staticmethod
20     def test3():
21         print TestClassMethod.METHOD
22         print 'test3'
23 
24 if __name__ == '__main__':
25     a = TestClassMethod()
26     a.test1()
27     a.test2()
28     a.test3()
29     TestClassMethod.test3()
30     TestClassMethod.test2()

test1
<__main__.TestClassMethod object at 0x0261FF30>
----------------
<class '__main__.TestClassMethod'>
test2
method hoho
----------------
method hoho
test3
----------------
<class '__main__.TestClassMethod'>
test2
method hoho
----------------
method hoho
test3
----------------

 

  __getattr__, __setattr__

    __getattribute__(self,name)  当特性name 被访问时自动被调用

    __getattr__(self,name) 当特性name 被访问,且没有响应的特性施被调用

    __setattr__(self,name,value) 当试图给特性name 赋值时使用

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

 

posted @ 2017-03-15 16:34  大愚者  阅读(209)  评论(0编辑  收藏  举报