gpt4 book ai didi

python - 如何替换/绕过类属性?

转载 作者:太空宇宙 更新时间:2023-11-04 10:10:25 28 4
gpt4 key购买 nike

我想要一个带有属性 attr 的类,当第一次访问时,运行一个函数并返回一个值,然后变成这个值(它的类型改变等)。

可以通过以下方式获得类似的行为:

class MyClass(object):
@property
def attr(self):
try:
return self._cached_result
except AttributeError:
result = ...
self._cached_result = result
return result

obj = MyClass()
print obj.attr # First calculation
print obj.attr # Cached result is used

但是,执行此操作时,.attr 不会成为初始结果。如果这样做,效率会更高。

一个难点是obj.attr设置为一个属性后,就不能轻易设置为其他东西了,因为死循环自然出现了。因此,在上面的代码中,obj.attr 属性没有 setter ,因此不能直接修改。如果定义了 setter,则替换此 setter 中的 obj.attr 会创建一个无限循环(从 setter 内部访问 setter)。我还想到了首先删除 setter 以便能够使用del self.attr 执行常规self.attr = …,但这会调用属性删除器(如果有的话),它会重新产生无限循环问题(在任何地方修改 self.attr 通常都倾向于通过属性规则)。

那么,有没有一种方法可以绕过属性机制并从 MyClass.attr.__getter__ 中用任何东西替换绑定(bind)属性 obj.attr

最佳答案

这看起来有点像过早的优化:你想通过改变描述符本身来跳过方法调用。

这是完全可能的,但必须证明这是合理的。

要从您的属性修改描述符,您必须编辑您的类,这可能不是您想要的。

我认为更好的实现方式是:

  • 不定义obj.attr
  • 覆盖__getattr__,如果参数是“attr”,obj.attr = new_value,否则引发AttributeError

一旦设置了obj.attr__getattr__ 将不再被调用,因为它只在属性不存在时被调用。 (__getattribute__ 会一直被调用。)

与您最初提议的主要区别是第一个属性访问速度较慢,因为 __getattr__ 的方法调用开销,但随后它将与常规 __dict__< 一样真实 查找。

示例:

class MyClass(object):

def __getattr__(self, name):
if name == 'attr':
self.attr = ...
return self.attr
raise AttributeError(name)

obj = MyClass()
print obj.attr # First calculation
print obj.attr # Cached result is used

编辑:请参阅the other answer ,尤其是当您使用 Python 3.6 或更高版本时。

关于python - 如何替换/绕过类属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38696819/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com