将类作为函数参数传递,并在函数中重复重置类

  • 本文关键字:函数 参数传递 python class
  • 更新时间 :
  • 英文 :


在我的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__)

现在,我想将此类的实例传递给我的 main 函数,并将该实例反复重置为其默认状态。尽管看了这里,这里,这里和这里,我还是无法让它继续下去。下面的工作示例给出了所需的结果,但显式重置了 main 函数中的实例。功能失调的例子是我使用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方法,我将不胜感激。

这样的事情怎么样:

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__)

下面是使用上下文管理器的实现:

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)

执行此操作的一种可重用方法是实现要继承的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类的基本假设是传递给构造函数的参数包含重置所需的所有信息,使用属性使该假设更容易满足。

最新更新