一.@property
在文章
python:面向对象程序设计及property装饰器
二.__slost__使用
先定义简单的一个类:
class Student: def __init__(self,name,age): self.name=name self.age=age
由于Python是可以动态绑定属性和方法的,一次,可以对一个雷或者类实例绑定一个属性.如果对一个对象绑定一个属性,该属性支队当前对象起作用,类的其他对象是没有这个属性的,
如:
if __name__ == "__main__": stu1 = Student('alex',18) #对stu1对象绑定一个nickname属性 stu1.nickname = 'littel alex' stu2 = Student('lisi',16) print(stu1.nickname) #'littel alex' # stu2没有nickname属性,因此出现异常 #print(stu2.nickname) #AttributeError: 'Student' object has no attribute 'nickname' print(stu1.nickname) #'littel alex' print(stu2.nickname) #AttributeError: 'Student' object has no attribute 'nickname'
在创建类时(如果没有使用__slots__属性),python会为每个实例串讲一个__dict__属性,以字典的形式存放每个实例的属性,我们分别打印stu1和sut2的__dict__属性:
print(stu1.__dict__) print(stu2.__dict__) ''' {'name': 'alex', 'age': 18, 'nickname': 'littel alex'} {'name': 'lisi', 'age': 16} '''
如果要对类的所有对象都绑定一个属性,name就要绑定在类上:
Student.nickname = 'litter student'
这时stu1和stu2都具有nickname属性了
如果进制对类进行属性的添加和删除,就要在定义类时定义一个特殊的__slots__属性即可,这样的类创建后将包含指定的元素,而没有__dict__属性,
如:
class Newstudent: __slots__ = ('name','age') def __init__(self,name,age): self.name=name self.age=age if __name__ == "__main__": stu1 = Newstudent('alex',1000) #由于使用__slots__指定了属性,不能再进行绑定, # 出现AttributeError: 'Newstudent' object has no attribute 'nickname' # stu1.nickname = 'wusix',9000 #AttributeError: 'Newstudent' object has no attribute 'nickname' #没有__dict__所以出现AttributeError print('dict:',stu1.__dict__) #AttributeError: 'Newstudent' object has no attribute '__dict__'
三.属性相关的特殊方法
通过@property装饰器可以快速简单的对属性进行控制,但是可读性差,因此,除了这种方式外,可以使用python内置的一些特殊方法老控制属性的存取,
这些方法见下表:
特殊方法 | 使用 | 描述 |
---|---|---|
__getattr__(self,item) |
v = obj.n | 返回obj对象的item属性 |
__setattr__(self, key, value) |
obj.key = value | 将obj对象的key属性设置为value |
__delattr__(self,item) |
v = obj.n | 删除obj对象的item属性 |
__dir__(self) |
dir(obj) | 返回obj对象的属性列表 |
__getattribute__(self,item) |
v = obj.n | 返回obj对象的item属性 |
例如通过上述方法对Student类中name属性进行控制:
def __setattr__(self, key, value): if key == 'name': if not isinstance(value,str): raise AttributeError("form setarr:name must be s str obj") self.__name = value
如果类中同事定义了__seattr__和@name.setter,执行哪一个?坑定是前者了.
''' 注意:如果要实现这些方法来对属性存取进行控制,应该左海条件判断,在设置的属性或值不符合时抛出AttributeError或ValueError. '''
__getattribute__()和_getattr__()方法都用于获取属性,在寻找属性时,其中如果实现了则__getattr__()不会调用.并且__getattribute__()通常会导致递归调用,因此一般不需要实现该方法.