在我的python脚本中,我定义了一个类似于以下(公认的)伪造类的类:
import copy
class Example:
def __init__(self, a, b):
self.a = a
self.b = b
self.__default__ = copy.deepcopy(self.__dict__)
self.t = 0
self.d = False
def do(self):
self.a += self.b - self.t
self.t += 1
if self.t == self.b:
self.d = True
return self.a
def reset(self):
self.__init__(**self.__default__)
现在,我想将此类的实例传递给我的主函数,并反复将该实例重置为其默认状态。尽管查看了here,here,here和here,但我还是无法理解。下面的工作示例提供了所需的结果,但仍在主函数中显式重置了该实例。功能失调的示例是我尝试使用reset
方法使其正常工作的众多尝试之一。
# working example:
def main(x):
agg = []
for i in range(x):
klass = Example(1, 3)
while not klass.d:
a = klass.do()
agg.append(a)
return agg
# dysfunctional example:
def main2(klass, x):
agg = []
for i in range(x):
klass.reset()
while not klass.d:
a = klass.do()
agg.append(a)
return agg
然后main(5)
给出
res = main(5)
print(res)
>>> [4, 6, 7, 4, 6, 7, 4, 6, 7, 4, 6, 7, 4, 6, 7]
而
ex = Example(1, 3) # default state
res = main2(ex, 5)
print(res)
引发错误:TypeError: __init__() got an unexpected keyword argument '__default__'
由于我想避免由于各种原因而不得不在主脚本中重新实例化该类,因此,如果有人可以通过reset
方法帮助我,我将不胜感激。
答案 0 :(得分:2)
那又怎么样呢?
class Example:
def __init__(self, *args, **kwargs):
"""This stores the default state then init the instance using this default state"""
self.__default_args__ = args
self.__default_kwargs__ = kwargs
self.init(*args, **kwargs)
def do(self):
"""Do whatever you want """
self.a += self.b - self.t
self.t += 1
if self.t == self.b:
self.d = True
return self.a
def init(self, a, b):
"""Inits the instance to a given state"""
self.a = a
self.b = b
self.t = 0
self.d = False
return self
def reset(self):
"""Resets the instance to the default (stored) state"""
return self.init(*self.__default_args__, **self.__default_kwargs__)
答案 1 :(得分:1)
这是使用上下文管理器的实现:
class Example:
def __init__(self, a, b):
self.a = a
self.b = b
self.t = 0
self.d = False
def do(self):
self.a += self.b - self.t
self.t += 1
if self.t == self.b:
self.d = True
return self.a
def __enter__(self):
self._a = self.a
self._b = self.b
def __exit__(self, *args):
self.t = 0
self.d = False
self.a = self._a
self.b = self._b
def main2(klass, x):
agg = []
for i in range(x):
with klass:
while not klass.d:
a = klass.do()
agg.append(a)
return agg
ex = Example(1, 3)
res = main2(ex, 5)
print(res)
答案 2 :(得分:0)
一种可重用的方法是实现要继承的Resettable
类。
class Resettable:
def __init__(self, *args, **kwargs):
self.__args__ = args
self.__kwargs__ = kwargs
def reset(self):
self.__init__(*self.__args__, **self.__kwargs__)
使用property
定义一个完全依赖于其他属性的属性也可以使重置过程更加顺畅。对于唯一需要及时往返的国家来说,拥有单一事实来源的想法通常是有用的范例。
class Example(Resettable):
def __init__(self, a=0):
self.a = a
super().__init__(a)
def do(self):
self.a += 1
return self.a
@property
def d(self):
return self.a > 3 # or any other condition
def main(instance, x):
agg = []
for _ in range(x):
instance.reset()
while not instance.d:
a = instance.do()
agg.append(a)
return agg
print(main(Example(), 3)) # [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
Resettable
类的基本假设是,传递给构造函数的参数包含重置所需的所有信息,使用属性使该假设更容易满足。