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 时被调用