phthon 魔法方法补充 __getattribute__ __setattr__ __getattr__

1. __getattribute__  

在访问实例属性时会最先调用__getattribute__方法,

例如:

class F(object):

    def __init__(self):
        self.name = 'A'

    def hello(self):
        print('hello')

    def __getattribute__(self, item):
        print('获取属性,方法', item)
        return object.__getattribute__(self, item)
    def next(self):
        print("next")
 
a = F()

print(a.name)

a.hello()

a.next()
获取属性,方法 name
A
获取属性,方法 hello
hello
获取属性,方法 next
next

若调用没有的方法test(),则会抛出异常.

获取属性,方法 test
Traceback (most recent call last):
  File "D:/spider_project/dianping/test.py", line 18, in <module>
    a.test()
  File "D:/spider_project/dianping/test.py", line 11, in __getattribute__
    return object.__getattribute__(self, item)
AttributeError: 'F' object has no attribute 'test'

如果要避免抛出没有方法的异常,可以设置__getattr__方法,调用一个默认的函数.

2.__getattr__

对没有定义的属性名和实例,会用属性名作为字符串调用这个方法

   class F(object):
        def __init__(self):
            self.name = 'A'
    
        def __getattr__(self, item):
            if item == 'age':
                return 40
            else:
                raise AttributeError('没有这个属性')
    
    f = F()
    print(f.age)

调用f.age,因为没有age这个属性 所以自动调用__getattr__方法,通过item判断这个属性是否等于age,是的话返回40,不是抛出异常.

3.__setattr__

拦截 属性的的赋值语句

class F(object):

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

a = F()
a.name = 'alex'
print(a.name)

设置属性

如何自定义私有属性:

class F(object):  # 基类--定义私有属性
    def __setattr__(self, key, value):
        if key in self.privs:
            raise AttributeError('该属性不能改变')
        else:
            self.__dict__[key] = value

重新设置在privs列表中的属性,则会抛出异常,

class F1(F):
    privs = ['age','name']  # 私有属性列表
x = F1()
x.name = 'egon'  # AttributeError: 该属性不能改变
x.sex = 'male'

name在privs列表中会报错,sex不在则不会.

class F2(F):
    privs = ['sex']      # 私有属性列表
    def __init__(self):
        self.__dict__['name'] = 'alex'

y = F2()
y.name = 'eva'

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值