python关于类的内置attr方法

1.__ getattr__(self, item)

object.__ getattr__(self, name)
Called when the default attribute access fails with an AttributeError (either __ getattribute__() raises an AttributeError because name is not an instance attribute or an attribute in the class tree for self; or __ get__() of a name property raises AttributeError). This method should either return the (computed) attribute value or raise an AttributeError exception.
Note that if the attribute is found through the normal mechanism, __ getattr__() is not called. (This is an intentional asymmetry between __ getattr__() and __ setattr__().) This is done both for efficiency reasons and because otherwise __ getattr__() would have no way to access other attributes of the instance. Note that at least for instance variables, you can fake total control by not inserting any values in the instance attribute dictionary (but instead inserting them in another object). See the __ getattribute__() method below for a way to actually get total control over attribute access.

当类的实例调用的属性或方法不存在时自动执行__getattr并报错; 在类中可以对其进行自定义修改,用此方法可实现不同类之间的授权操作;但不能实现真正的属性访问控制.

2.__ setattr__(self, key, value)

object.__ setattr__(self, name, value)
Called when an attribute assignment is attempted. This is called instead of the normal mechanism (i.e. store the value in the instance dictionary). name is the attribute name, value is the value to be assigned to it.
If __ setattr__() wants to assign to an instance attribute, it should call the base class method with the same name, for example, object.__ setattr__(self, name, value).

当类的实例进行修改或添加属性时实质上就是执行__setattr方法;可在类中对其进行自定义修改,可导致其不能成功修改属性.

3.__ delattr__(self, item)

object.__ delattr__(self, name)
Like __ setattr__() but for attribute deletion instead of assignment. This should only be implemented if del obj.name is meaningful for the object.

当类的实例进行删除属性时实质上就是在执行__delattr方法;可在类中对其进行自定义修改,让其无法成功删除属性.

示例1:setattr与getattr

class Test:
    addr = 'beijing'
    def __init__(self, a):
        self.name = a

    def __setattr__(self, key, value):
        print('setattr')

    def __delattr__(self, item):
        print('delattr')

    def __getattr__(self, item):
        print('getattr')
        #return getattr([1,2,3], item)


f1 = Test('sabi')
Test.age = 18  # 未触发setattr
f1.gender = 'male'  # 触发setattr
print(f1.__dict__)  # 增加属性未成功
print(Test.__dict__) # 增加属性成功
f1.__len__  # 触发getattr
Test.addrs  #不会触发getattr,会报错

#result
setattr
setattr
{}
{'__module__': '__main__', 'addr': 'beijing', '__init__': <function Test.__init__ at 0x000002C3F89097B8>, '__setattr__': <function Test.__setattr__ at 0x000002C3F8909840>, '__delattr__': <function Test.__delattr__ at 0x000002C3F89098C8>, '__getattr__': <function Test.__getattr__ at 0x000002C3F8909950>, '__dict__': <attribute '__dict__' of 'Test' objects>, '__weakref__': <attribute '__weakref__' of 'Test' objects>, '__doc__': None, 'age': 18}
getattr

示例2: delattr

class Test:
    addr = 'beijing'
    def __init__(self, a):
        self.name = a

    def __setattr__(self, key, value):
        #print('setattr')
        self.__dict__[key] = value

    def __delattr__(self, item):
        print('delattr')

    def __getattr__(self, item):
        print('getattr')
        #return getattr([1,2,3], item)


f1 = Test('sabi') # 增加属性成功
Test.age = 18  # 未触发setattr
f1.gender = 'male'  # 触发setattr
print(f1.__dict__)  # 增加属性成功
f1.__len__  # 触发getattr
del f1.gender # 未成功删除
del Test.addr #删除属性成功
print(f1.__dict__)
print(f1.name)
#print(Test.addr) # 报错

#result
{'name': 'sabi', 'gender': 'male'}
getattr
delattr
{'name': 'sabi', 'gender': 'male'}
sabi

使用注意:1. 如果上述方法在类中被设置.则其子类会同样继承这样的设置,而不会使用原来的内置方法2.上述3个内置方法只对实例有效,和类无关
实例3:子类继承

class Test:
    addr = 'beijing'
    def __init__(self, a):
        self.name = a

    def __setattr__(self, key, value):
        print('setattr')
        #self.__dict__[key] = value

    def __delattr__(self, item):
        print('delattr')

    def __getattr__(self, item):
        print('getattr')
        #return getattr([1,2,3], item)


class Test2(Test):
    def __init__(self, name):
        self.name = name

f2 = Test2('sabi')
f2.abc
print(f2.__dict__)

#result
setattr
getattr
{}

实例4: getattr方法用于授权操作

class Test:
    addr = 'beijing'
    def __init__(self, filename, mode, encoding = 'utf-8'):
        self.name = open(filename, mode, encoding=encoding)
        self.mode = mode
        self.encoding = encoding

    def testing(self):
        print('abc')

    def __setattr__(self, key, value):
        print('setattr')
        self.__dict__[key] = value

    def __delattr__(self, item):
        print('delattr')
        del self.__dict__.pop[item]

    def __getattr__(self, item):
        print('getattr')
        #return self.name.item
        return getattr(self.name, item)  #用此种方法调用文件的内置方法

f = Test('ab.txt', 'w')
print(f.__dict__)
f.write('aabbcc')

#result
setattr
setattr
setattr
{'name': <_io.TextIOWrapper name='ab.txt' mode='w' encoding='utf-8'>, 'mode': 'w', 'encoding': 'utf-8'}
getattr

4.__ getattribute__(self, item)

此内置方法是实例调用属性时会自动执行的方法(不论能否找到),如果找不到则抛出异常AttributeError,并继续执行__ _getattr方法,如果getattr方法也找不到则报错,可实现真正的属性访问控制.
注意:此内置方法涉及功能较多,最好不要随意修改, 例如会使–dict–方法无法使用.

object.__ getattribute__(self, name)
Called unconditionally to implement attribute accesses for instances of the class. If the class also defines __ getattr__(), the latter will not be called unless __ getattribute__() either calls it explicitly or raises an AttributeError. This method should return the (computed) attribute value or raise an AttributeError exception. In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same name to access any attributes it needs, for example, object.__ getattribute__(self, name).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值