gpt4 book ai didi

python - 如何从类外部定义的 __setattr__ 实现正确设置属性

转载 作者:行者123 更新时间:2023-11-30 22:30:17 24 4
gpt4 key购买 nike

我想定义一个返回 __setattr__ 的通用实现的函数,该函数使属性不可设置,除非它们是属性(我应该一般测试数据描述符,但那是稍后的事情) )。该函数如下所示:

def make_setattr(doc='Immutable attributes'):
def __setattr__(self, name, value):
if isinstance(getattr(type(self), name, None), property):
super(type(self), self).__setattr__(name, value)
raise AttributeError('Please stop trying!')
__setattr__.__doc__ = doc
return __setattr__

这是一个显示用法的示例:

class A:
__setattr__ = make_setattr()

@property
def x(self):
return 1

@x.setter
def x(self, name):
pass


class B(A):
pass

这似乎适用于非属性属性:

>>> a = A()
>>> a.y = 1
AttributeError: Please stop trying!
>>> a.y
AttributeError: 'A' object has no attribute 'y'

>>> b = B()
>>> b.y = 1
AttributeError: Please stop trying!
>>> b.y
AttributeError: 'B' object has no attribute 'y'

但是,它对于属性属性却严重失败:

>>> a.x = 1
AttributeError: Please stop trying!
>>> b.x = 1
RecursionError: maximum recursion depth exceeded while calling a Python object

a上设置属性似乎完全忽略了x是一个属性的事实。将其设置为 b 会进入无限递归 super(type(self), self).__setattr__(name, value)。这两个调用的行为就好像 super(type(self), self) 的结果返回 __setattr__ 的错误实现。

我尝试通过删除 super 的参数来缓解此问题:super().__setattr__(name, value),但是 a.x = 1b.x = 1 加注

RuntimeError: super(): __class__ cell not found

如何在外部定义的方法中找到并调用 __setattr__ 的正确父实现?在这种情况下,如果可能的话,我想避免显式调用 object.__setattr__

最佳答案

一个简单的解决方法是显式调用属性的 setter 函数,而不是使用 super(...).__setattr__:

def make_setattr(doc='Immutable attributes'):
def __setattr__(self, name, value):
prop = getattr(type(self), name, None)
if isinstance(prop, property):
prop.__set__(self, value)
else:
raise AttributeError('Please stop trying!')
__setattr__.__doc__ = doc
return __setattr__

关于python - 如何从类外部定义的 __setattr__ 实现正确设置属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46121637/

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