9.5属性
如果在访问给定的特性时必须要采取一些行动,那么像这样的封装状态变量就很重要。
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
9.5.1property函数
Property函数使用简单,只需在上述rectangle类上增加一行代码比如:子类化object或者使用__metclass__=type
__metclass__=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)
在这里,property创建了一个属性,其中访问器函数被用做参数,这个属性命为size
>>>r=Rectangle()
>>>r.width=10
>>>r.height=5
>>>r.size
(10,5)
>>>r.size=150,100
>>>r.width
10
9.5.2静态方法和类成员方法
静态方法的定义没有self参数,且能够被类本身直接调用,类方法在定义时需要名为cls的类似于self的参数,类成员方法可以直接用类的具体对象调用,但cls参数是自动被绑定到类的:
__metclass__=type
class Myclass:
def smeth():
print 'this is a static method'
smeth=staticmethod(smeth)
def cmeth(cls):
print 'this is a class method of',cls
cmeth=classmethod(cmeth)
这样有些单调,其实可以使用装饰器,使用@操作符,在方法的上方将装饰器列出,从而制定一个或者更多的装饰器
__metclass__=type
class Myclass:
@staticmethod
def smeth():
print 'this is a static method'
@classmethod
def cmeth(cls):
print 'this is a class method of',cls
运行结果都是一样的
>>>Myclass.smeth()
thisis a static method
>>>Myclass.cmeth()
thisis a class method of __builtin__.Myclass
9.5.3__getattr__、__setattr__
拦截对象的所有特性访问是可能的,这样可以用旧式类实现属性
__getattribute__(self.name):当特性name被访问时自动被调用
__getattr__(self,name):当特性name被访问且对象没有相应的特性时被自动调用
__setattr__(self.name.value):当时图给特性name赋值是会被自动调用
__delattr__(self,name):当试图删除特性name是被自动调用
继续rectangle的例子:、
class Rectangle:
def __init__(self):
self.width=0
self.height=0
def __setattr__(self, name, value):
if name=='size':
self.width,self.height=value
else:
self.__dict__[name]=value
def __getattr__(self, name):
if name=='size':
return self.width,self.height
else:
raise AttributeError