python笔记
1. 实例变量隐藏类变量:
x = 1
mc = MyClass()
print mc.x # 1
mc.x = 2
print mc.x # 2
print MyClass.x # 1
如果是可变的类属性的话,就不会隐藏类属性,而是直接修改类属性。
x = {'num': 1}
mc = MyClass()
print mc.x # {'num': 1}
mc.x['price']=200
print mc.x # {'price': 200, 'num': 1}
2. super, __getattribute__, __getattr__
#!/usr/bin/env python
class MyClass(object):
x = 10
def __getattr__(self, key):
print '__getattr__'
mc = MyClass()
mc.y # __getattr__
print mc.x # 10
Notes: 访问不存在的y属性,会调用到__getattr__
#!/usr/bin/env python
class MyClass(object):
x = 10
def __getattr__(self, key):
print '__getattr__'
def __getattribute__(self, key):
print '__getattribute__'
return super(MyClass, self).__getattribute__(key)
mc = MyClass()
print mc.x # __getattribute__
# 10
Notes: 当__getattr__和__getattribute__同时存在,不管访问存在或是不存在的属性,都会先调用__getattribute__。
所以__getattr__永远不会被调到。
另外,在__getattribute__的函数中,不能直接访问self的属性(会导致再次调用__getattribute__,然后死循环),
应该使用super(obj, self).__getattribute__(key),类似这样的方法。对于class的属性(例如这里的x),也可以
直接用MyClass.x来访问。
#!/usr/bin/env python
class MyClass(object):
x = 10
def __getattr__(self, key):
print '__getattr__'
def __getattribute__(self, key):
print '__getattribute__'
return super(MyClass, self).__getattribute__(key)
mc = MyClass()
mc.x = 20 # __getattribute__
print mc.x # 20
Notes: 同样,__getattribute__也会先访问instance的属性。
3. descriptors and properties
#!/usr/bin/env python
class Celsius(object):
def __init__(self, value=0.0):
self.value = float(value)
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
self.value = float(value)
class Farenheit(object):
def __get__(self, instances, owner):
return instances.celsius * 9/5 + 32
def __set__(self, instances, value):
instances.celsius = (float(value) - 32) * 5/9
class Temperature(object):
celsius = Celsius()
farenheit = Farenheit()
oven= Temperature()
oven.farenheit=450
print oven.celsius # 232.222222222
oven.celsius = 175
print oven.farenheit # 347.0
descriptor简单来看就是把对属性的访问,通过一个descriptor class来间接访问。
这个class可以有__get__, __set__, __delete__这些方法来实现属性的读,写,删除。
我们可以把相关的属性值放在descriptor class里面,比如上面例子里的class Celsius,用self.value来
保存属性值。
也可以放在descriptor class owner里面,所谓owner,就是使用descriptor class的类,就像Temperature。
例子中的class Farenheit,本身没有保存属性值,而是使用class Temperature的属性(celsius)。对于这种情况,
需要用到__get__, __set__中的第二个参数(instance)。
#!/usr/bin/env python
class Temperature( object ):
def fget( self ):
return self.celsius * 9 / 5 + 32
def fset( self, value ):
self.celsius= (float(value)-32) * 5 / 9
farenheit= property( fget, fset )
def cset( self, value ):
self.cTemp= float(value)
def cget( self ):
return self.cTemp
celsius= property( cget, cset, doc="Celsius temperature" )
oven= Temperature()
oven.farenheit= 450
print oven.celsius # 232.222222222
oven.celsius= 175
print oven.farenheit # 347.0
property就比较简单了,看看这个例子,估计你就知道什么意思了 :)
4.
http://blog.donews.com/limodou/archive/2004/12/19/207521.aspx
http://www.cnblogs.com/coderzh/archive/2010/04/27/python-cookbook33-decorators.html