__getattr__ 与动态属性

直接上代码

>>> class Test(object):
...     def __getattr__(self,attr_name):
...             setattr(self, attr_name, '(default)')
...             return self.attr_name
... 
>>> t=Test()
>>> t.name
'(default)'
>>> t.age
'(default)'
>>> t.name='smith'
>>> t.name
'smith'
>>> t.age=38
>>> t.age
38

 

是不是感觉节操碎了一地?

 

原理剖析:

默认:

class_object.attr   --> 去 class_object.__dict__中寻找 attr的属性 --(没找着)---> class.__dict__ ----(没找者) ----> parent_class.__dict__---(没找着)----> 抛出异常 AttrbiuteError

当class定义了自己的__getattr__(而不是__getattribute__, 慎重写)时,寻找逻辑是这样的:

class_object.attr   --> 去 class_object.__dict__中寻找 attr的属性 --(没找着)---> class.__dict__ ----(没找者) ----> 调用class的__getattr__来动态“生成”属性(返回对应属性的值,没有return则为None)

 

转载请注明来源:http://www.cnblogs.com/Tommy-Yu/p/5480975.html

参考:http://m.jb51.net/article/59908.htm

谢谢!

转载于:https://www.cnblogs.com/Tommy-Yu/p/5480975.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`__get__` 和 `__getattr__` 都是 Python 中的特殊方法,但它们的作用不同。 `__get__` 通常与描述器一起使用,用于控制属性的获取行为。当我们访问一个对象的属性时,如果这个属性有对应的描述器对象,就会调用这个描述器对象的 `__get__` 方法来获取属性的值。如果一个类定义了一个描述器,那么这个描述器实例的 `__get__` 方法将会被调用来获取属性值。 `__getattr__` 是一个对象的特殊方法,用于在访问一个对象的属性时,如果这个属性不存在,就会自动调用 `__getattr__` 方法,并返回一个默认值或抛出一个异常。`__getattr__` 方法接收一个参数 `name`,表示访问的属性名,如果对象有这个属性,则直接返回属性值;如果没有,可以返回一个默认值或者抛出一个 `AttributeError` 异常。 下面是一个示例来说明这两个方法的不同: ```python class Descriptor: def __get__(self, instance, owner): print("Getting the attribute...") return instance._attr class MyClass: attr = Descriptor() def __init__(self, value): self._attr = value def __getattr__(self, name): if name == 'non_existent_attr': return 'default_value' else: raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'") ``` 在上面的例子中,我们定义了一个描述器 `Descriptor`,并将其作为 `MyClass` 中属性 `attr` 的值。`MyClass` 中还定义了一个 `__getattr__` 方法,用于处理不存在的属性访问。当我们访问 `MyClass` 实例的属性 `attr` 时,会调用 `Descriptor` 中的 `__get__` 方法,从而打印出 "Getting the attribute..." 并返回 `_attr` 的值。当我们访问 `MyClass` 实例的不存在的属性 `non_existent_attr` 时,会调用 `__getattr__` 方法,并返回默认值 "default_value"。 ```python >>> obj = MyClass(10) >>> obj.attr Getting the attribute... 10 >>> obj.non_existent_attr 'default_value' >>> obj.unknown_attr AttributeError: 'MyClass' object has no attribute 'unknown_attr' ``` 在上面的例子中,我们首先创建了一个 `MyClass` 的实例 `obj`,并将其初始化为 10。接着我们访问了 `obj` 的属性 `attr`,这会打印出 "Getting the attribute..." 并返回 10。然后我们访问了 `obj` 的不存在的属性 `non_existent_attr`,这会直接返回默认值 "default_value"。最后我们访问了 `obj` 的未知属性 `unknown_attr`,这会触发 `__getattr__` 方法,并抛出一个 `AttributeError` 异常。 总之,`__get__` 和 `__getattr__` 的作用不同。`__get__` 通常用于描述器中控制属性的获取行为,而 `__getattr__` 用于处理不存在的属性访问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值