python:面向对象程序设计进阶(一):控制属性的三种方式 python:面向对象程序设计及property装饰器

一.@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__()通常会导致递归调用,因此一般不需要实现该方法.

猜你喜欢

转载自www.cnblogs.com/while-number/p/9272423.html
今日推荐