我上课了
Python(3)中的javax.validation.constraints.NotNull
,当然包含Foo
方法。这个类会触发一些提示并完成它的工作。假设我希望能够重置__init__()
,以便我可以重新开始这个过程。
什么是首选实施?
再次调用Foo
方法
__init__()
或创建新实例?
def reset(self):
self.__init__()
如果多次调用def reset(self):
Foo()
,我不确定创建Foo
的新实例是否会留下可能影响性能的任何内容。另一方面,reset
可能会产生副作用,如果不是__init__()
中(重新)定义了所有属性。
有没有首选的方法呢?
答案 0 :(得分:7)
两者都是正确的,但语义没有以相同的方式实现。
为了能够重置一个实例,我会写这个(我更喜欢从__init__
调用自定义方法而不是相反,因为__init__
是一种特殊的方法,但这主要是一个问题味道):
class Foo:
def __init__(self):
self.reset()
def reset(self):
# set all members to their initial value
你这样使用它:
Foo foo # create an instance
...
foo.reset() # reset it
从头开始创建一个新实例实际上更简单,因为该类没有实现任何特殊方法:
Foo foo # create an instance
...
foo = Foo() # make foo be a brand new Foo
如果旧实例未在其他任何地方使用,则会对其进行垃圾回收
两种方式都可用于普通类,其中所有初始化都在__init__
中完成,但第二种方式是在创建时使用{{1}自定义的特殊类所必需的},例如不可变类。
但要注意,这段代码:
__new__
将不执行您想要的操作:它只会创建一个新实例,并立即将其删除,因为它将在方法结束时超出范围。甚至def reset(self):
Foo()
只会在方法结束时设置本地引用,这些引用会超出范围(并且新实例被销毁)。
答案 1 :(得分:3)
您可以在类属性中保存您使用的实例。 无论何时想要重置类,都要将新实例重新分配给该属性。 以下是我将如何实现这种方法:
class Foo:
instance = None # The single instance
def __init__(self, ...):
# Initialize the instance if Foo.instance does not exist, else fail
if type(self).instance is None:
# Initialization
type(self).instance = self
else:
raise RuntimeError("Only one instance of 'Foo' can exist at a time")
@classmethod
def reset(cls):
cls.instance = None # First clear Foo.instance so that __init__ does not fail
cls.instance = Foo(...) # Now the initialization can be called
然后,您只需引用Foo.instance
。
我选择reset
作为类方法,因此由@classmethod
修饰。
使用此装饰器,可以通过调用Foo.reset()
重置实例,cls
参数将自动传递给方法。
我更喜欢这种方法(或多或少是单一模式)而不是你建议的方法,因为在你的情况下,拥有Foo
的单个实例似乎是合乎逻辑的,因为你想重置它。
因此,我发现它非常直观,强迫"使用单个实例。
另一方面,你可以在类之外有一个实例,并使用reset
实例方法,定义:
def reset(self):
self.__init__()
但这可能效果不太好。
假设您要在__init__
方法之外设置属性。
调用__init__
不会重置这些属性。
因此,您的实例不会按预期重置。
现在,如果你持有一个实例并将其重新分配给一个全新的实例,那么你就确定它绝对是干净的。
关于你所谓的"创建一个新实例" ,这或多或少是我选择的,但问题是在哪里存储它。 我认为在课堂上保持温暖是有道理的。
顺便说一句,使用此解决方案不应该出现任何性能问题(例如,内存泄漏"),因为一次只引用一个Foo
实例,并且创建一个新的将取消引用前一个。
答案 2 :(得分:0)
正如其他人所说,您不需要重置课程。但是如果你真的想要它,你可以使用一个工厂函数,每次调用都会返回一个新类。
def make_Foo():
class Foo():
VALUE = 1
return Foo
Foo = make_Foo()
Foo.VALUE = 2
print(Foo.VALUE) # prints 2
Foo = make_Foo() # reset
print(Foo.VALUE) # prints 1