我试图理解如何在调用对象时临时更改其属性,并在不调用对象时保持原始值。你知道吗
让我用一些代码来描述这个问题:
class DateCalc:
DEFAULT= "1/1/2001"
def __init__(self, day=DEFAULT):
self.day= day
def __call__(self, day=DEFAULT):
self.day= day
return self
def getday(self):
return self.day
如果用户在传递另一个值时调用getday方法 i、 2002年2月2日,自我保护日设定为2002年2月2日。但是我希望能够恢复自我保护日方法调用后的原始值1/1/2001:
d_obj = DateCalc()
d_obj.getday() == "1/1/2001"
True
d_obj().getday() == "1/1/2001"
True
another_day_str = "2/2/2002"
d_obj(another_day_str).getday()
退货
"2/2/2002"
但当我运行以下命令时
d_obj.getday()
退货
"2/2/2002"
我想知道什么是还原值的正确方法,而不需要在每个方法调用中包含代码。其次,在调用对象时也应该如此。例如:
d_obj().getday()
你应该回来
"1/1/2001"
我以为调用魔术方法的装饰器在这里可以工作,但我不确定从哪里开始。你知道吗
任何帮助都将不胜感激
似乎您需要一种类似于上下文管理器的行为:要在有限的时间内修改属性,请使用更新的属性,然后还原为原始属性。您可以让
__call__
返回一个上下文管理器,然后在with
块中使用它,如下所示:有几种方法可以创建这样的上下文管理器。最简单的方法是使用} 装饰它:
__call__
中的嵌套方法,并用^{您也可以为此使用一个完全成熟的嵌套类,但除非您有一些非常复杂的需求,否则我不推荐使用它。我只是提供完整性:
另外,您应该考虑将
getday
设为属性,特别是如果它确实是只读的。你知道吗另一种选择是让您的方法接受不同的值:
这其实是一个相当普遍的成语。你知道吗
由于您可能并不真的希望修改对象的属性以获得一个定义不好的间隔,因此您需要返回或以其他方式创建一个不同的对象。你知道吗
最简单的情况是,您有两个独立的对象,并且根本没有
__call__
方法:如果您知道在原始情况下要在何处使用
d_obj
对d_obj()
,那么您也清楚地知道在这个版本中在何处使用d1_obj
对d2_obj
。你知道吗这对于
DateCalc
实际表示一个非常复杂的对象的情况来说可能是不够的,这个对象有许多您不想更改的属性。在这种情况下,可以让__call__
方法返回一个独立的对象,该对象智能地复制所需的原始部分。你知道吗对于一个简单的例子,这可能只是
如果对象变得足够复杂,则需要创建代理。代理是将大部分实现细节转发给另一个对象的对象。^{} 是具有高度定制的^{} 实现的代理的一个示例。你知道吗
在您的特定情况下,您有几个要求:
self
参数传递给任何被调用的(至少是非特殊的)方法。你知道吗您可以随心所欲地处理这个问题(在这种情况下,可以查看如何正确实现代理对象,如here)。下面是一个相当简单的例子:
代理将完全按照您所希望的方式工作:它从原始对象转发您在
__call__
中未重写的任何值。有趣的是,它将实例方法绑定到代理对象而不是原始对象,这样getday
就会被一个self
调用,其中包含重写的值:请记住,这里显示的代理对象实现的功能非常有限,在许多情况下无法正常工作。也就是说,它很可能涵盖了许多您将拥有的开箱即用的用例。一个很好的例子是,如果您选择将
day
作为一个属性,而不是使用getter(这是一种更为python的方法):这里需要注意的是,代理版本的
day
只是一个常规的可写属性,而不是只读属性。如果这对您来说是个问题,那么在代理上适当地实现__setattr__
将留给读者作为练习。你知道吗相关问题 更多 >
编程相关推荐