zoukankan      html  css  js  c++  java
  • python:面向对象程序设计进阶(一):控制属性的三种方式

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

  • 相关阅读:
    ZJOI2017 Day3 滚粗记
    ZJOI2017 Day2
    bzoj4245 [ONTAK2015]OR-XOR (贪心)
    bzoj4631 踩气球 (树状数组+线段树)
    bzoj5219 [Lydsy2017省队十连测]最长路径 (DP)
    bzoj5216 [Lydsy2017省队十连测]公路建设 (线段树)
    bzoj2754 [SCOI2012]喵星球上的点名 (后缀数组+树状数组)
    bzoj2342 [Shoi2011]双倍回文 (manacher)
    bzoj4657 tower (最小割)
    bzoj2064 分裂 (状压dp)
  • 原文地址:https://www.cnblogs.com/while-number/p/9272423.html
Copyright © 2011-2022 走看看