gpt4 book ai didi

python - 如何识别属性的属性何时被设置?

转载 作者:太空狗 更新时间:2023-10-30 02:27:23 25 4
gpt4 key购买 nike

我有一个具有多个属性的可变对象(我们称之为 mutable)。该对象本身是 Foo 类中的一个属性。 Foo 是用户定义的,而 mutable 不是,因此不能更改。

每当有人试图在 mutable 中设置属性时,我都需要进行计算。我面临的问题是,使用 mutable 的属性仅在设置了 mutable 本身而不是其属性时才有效。我已经设法解决了这个问题,但使用的东西似乎比合理的 Python 代码更像是 hack。

class Mutable(object):  # Example class.

def __init__(self):
self.attr0 = 0
self.attr1 = 1

def __repr__(self):
return str(self.__dict__)[1:-1]


class Foo(object):

def __init__(self):
self._mutable = Mutable()

@property
def mutable(self):
print('mutable was read')
return self._mutable

@mutable.setter
def mutable(self, attr_value_pair):
attribute, value = attr_value_pair
setattr(self._mutable, attribute, value)
print('mutable.' + attribute, 'was set to', value)


bar = Foo()
print(bar.mutable) # 'mutable was read'
bar.mutable = ('attr0', 5) # 'mutable.attr0 was set to 5'
bar.mutable = ('attr1', 10) # 'mutable.attr1 was set to 10'
print(bar.mutable) # 'mutable was read'

# This is what I want to do but it only calls the getter.
bar.mutable.attr0 = 0 # 'mutable was read'
bar.mutable.attr1 = 1 # 'mutable was read'

有什么方法可以识别 mutable 中的属性何时以更 Pythonic 的方式设置?

编辑: 澄清一下:Foo 需要知道 mutable 何时更改,因为 Foo 具有依赖于可变Mutable 可以被继承。

最佳答案

最简单干净的解决方案是子类化 mutable - 但我认为这不是一个选项。

最简单的“quick&dirty”解决方案是使用 monkeypatch mutable - 但这实际上是最后的解决方案,从长远来看是在寻找麻烦。

因此,如果您不能将 mutable 子类化,也不能控制它的实例化,并且不想对其进行 monkeypatch,那么您只能使用 proxy 模式。

编辑:哦,是的,因为它是 Foo 需要得到关于 self._mutable 更改的通知,你必须将它与观察者模式结合起来(这里是非常有限的形式):

class Mutable(object):  # Example class.

def __init__(self):
self.attr0 = 0
self.attr1 = 1

def __repr__(self):
return str(self.__dict__)[1:-1]



class MutableProxy(object):
def __init__(self, mutable, owner):
self._mutable = mutable
self._owner = owner

@property
def attr0(self):
return self._mutable.attr0

@attr0.setter
def attr0(self, value):
self._mutable.attr0 = value
self._owner.notify("set", "attr0", value)


@property
def attr1(self):
return self._mutable.attr1

@attr1.setter
def attr1(self, value):
self._mutable.attr1 = value
self._owner.notify("attr1", value)

def __repr__(self):
return "<MutableProxy for {}>".format(repr(self._mutable))

class Foo(object):
def __init__(self):
self.mutable = Mutable()

@property
def mutable(self):
#print('mutable was read')
return self._mutable

@mutable.setter
def mutable(self, value):
self._mutable = MutableProxy(value, self)

def notify(self, attrname, value):
print('self._mutable.{} was set to {}'.format(attrname, value))

注意:我没有在 MutableProxy.__init__ 中添加任何类型检查,这取决于你真正的 mutable 实际上是什么你可能想要确保你至少得到一些东西兼容...

NB2:我在 ProxyMutable 上使用了显式属性,因为它使事情更清晰,但您可能想使用 __getattr__/__setattr__ Hook (至少对于您不需要控制访问的 mutable 属性)。

NB3:我们现在在 FooMutableProxy 之间有一个循环引用。 Python normalluy 知道如何摆脱循环引用,但如果它碰巧仍然是您的具体用例的问题,您可能希望将 MutableProxy._owner 设置为 weak reference相反。

现在困扰我的问题是:为什么要公开 mutable ?完全隐藏它并仅通过 Foo 方法或属性提供对其属性的访问将使代码更简单(并且更容易推理并且不太可能产生意外副作用)。

关于python - 如何识别属性的属性何时被设置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41330968/

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