【发布时间】:2017-01-27 09:02:25
【问题描述】:
我正在编写一个自定义类型Foo,我想实现以下目标:编写时
foo = Foo(bar)
那么如果bar 已经是Foo 的一个实例,那么Foo(foo) 会返回未修改的对象,所以foo 和bar 指的是同一个对象。否则,应该使用来自bar 的信息以Foo.__init__ 认为合适的任何方式创建一个Foo 类型的新对象。
我该怎么做?
我认为Foo.__new__ 是解决这个问题的关键。如果instanceof 检查成功,让Foo.__new__ 返回现有对象应该相当容易,否则调用super().__new__。但是the documentation for __new__ 写道:
如果
__new__()返回一个cls的实例,那么新实例的__init__()方法将像__init__(self[, ...])一样被调用,其中self是新实例并且其余参数与传递给__new__()的参数相同。
在这种情况下,我将返回所请求类的一个实例,尽管不是一个新实例。我可以以某种方式阻止对__init__ 的调用吗?还是我必须在__init__ 中添加一个检查,以检测它是为新创建的实例还是为已经存在的实例调用?后者听起来像是应该可以避免的代码重复。
【问题讨论】:
-
不可以用工厂方法来实现吗?
-
@Tagc:我有点习惯于使用构造函数名称进行强制转换。例如
float(x)、str(x)或tuple(x),如果它已经是正确的类型,则返回相同的对象。我经常使用这种表示法,所以我也希望我自己的类型也能保持一致。所以这是风格问题,我猜。从功能上讲,工厂方法当然也可以正常工作。
标签: python python-3.x constructor casting