python : class定义中的:__dict__,__setattr__,__getattribute__,__getattr__,

 __setattr__,__getattribute__,__getattr__是三个python的与类(class)定义相关的内置函数,与类(class)实例的属性的“赋值”与“调用”有关。

1) 与类属性“赋值”相关

__setattr__: 与类实例的属性的“赋值”操作有关,类实例的任何属性赋值操作都会自动调用该内置函数。该内置函数的默认作用是:将类实例的属性名与对属性的赋值以字典的形式存放在__dict__中,__dict__是python为每个class专门配置的一个字典,用于存储类属性与属性值。

        无论一个属性有没有在类中被定义,在为该类实例增加该属性并为该属性赋值时,都会自动调用__setattr__

2) 与类属性“调用”相关

__getattribute__:当调用一个类实例的属性时,无论该属性是否存在,都会自动调用__getattribute__函数。该函数的默认操作是:先查看该类实例的__dict__中是否包含要调用的属性,如果有则返回属性值;如果没有,则发出KeyError或AttributeError信号,然后返回属性值为None.

        默认情况下__getattribute__函数不对AttributeError的情况进行处理,此时AttributeError会继续存在,自动触发__getattr__函数,__getattr__中的所有操作是对AttributeError的情况的应对。

        如果通过程序员手工修改__getattribute__函数,使__getattribute__拥有了对AttributeError的处理操作,则AttributeError会消失,不再被后传到__getattr__函数,也就不会触发__getattr__的操作。

############################################################################

综上:python在类实例的定义过程中,自动为该类实例分配了一个用于存储类实例属性的字典“__dict__”。

           __setattr__:通过向__dict__中添加key与value,设置类实例的属性。不论这个属性有没有在类定义中被定义,都不影响此操作向__dict__中添加key与value。

备注:赋值与调用是两个独立的过程,赋值过程不存在调用,因此不会触发__getattribute__函数。

测试代码如下:    

class AboutAttr(object):
    def __init__(self,name):
        self.name=name

    def __setattr__(self,attribute_name,value):
        print('触发了__setattr__,被赋值的属性名为:{},赋的值为:{}'.format(attribute_name,value))
        # self.__dict__[attribute_name]=value  ## 将属性值存放到__dict__中

    def __getattribute__(self, attribute_name):
        ##  函數功能:获取属性值。只要调用属性,该函数就会被调用。 自动先搜索 __dict__,判断属性名是否已存在,
        ## 然后再选择相应的操作。
        print('触发了 __getattribute__,被调用的属性名为:{}'.format(attribute_name))
        try:
            return super(AboutAttr, self).__getattribute__(attribute_name)

        except AttributeError as ex:
            print("__getattribute__ 处理了 AttributeError异常")
            # return 'AttributeError dealed '


    def __getattr__(self, attribute_name):
        print('触发了 __getattr__')
        return 'default'



if __name__=='__main__':
    at = AboutAttr('test')

    print('\n操作:at.name')
    at.name='hello world'

    print('\n操作:at.age')
    at.age=100

    print('\n操作:at.height')
    at.height=180

    print("\n#######调用操作#######")
    print('\n操作,调用已被定义属性:print(at.name)')
    print(at.name)

    print('\n操作,调用已被定义属性:print(at.age)')
    print(at.age)

    print('\n操作,调用已被定义属性::print(at.height)')
    print(at.height)

    print('\n操作:调用未被定义属性:print(at.not_exist)')
    print(at.not_exist)

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值