python – 作为幂等类型转换函数的类名

我正在写一个自定义类型Foo,我想要实现以下目标:写作时

foo = Foo(bar)

然后如果bar已经是Foo的一个实例,那么Foo(foo)会返回该对象未修改,因此foo和bar引用同一个对象.否则,应该使用来自bar的信息以Foo .__ init__认为合适的方式创建类型为Foo的新对象.

我怎样才能做到这一点?

我认为Foo .__ new__是关键.如果检查实例成功,那么让Foo .__ new__返回现有对象应该相当容易,否则调用super().__ new__.但the documentation for __new__写道:

If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like __init__(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to __new__().

在这种情况下,我将返回所请求类的实例,尽管不是新实例.我可以以某种方式阻止对__init__的调用吗?或者我是否必须在__init__中添加一个检查来检测是为新创建的实例还是为现有实例调用它?后者听起来像代码重复,应该是可以避免的.

最佳答案 恕我直言,你应该直接使用__new__和__init__.在init中进行的测试,看看你是否应该初始化一个新对象或者已经有一个现有对象是如此简单,以至于没有代码重复,增加的复杂性是恕我直言

class Foo:
    def __new__(cls, obj):
        if isinstance(obj, cls):
            print("New: same object")
            return obj
        else:
            print("New: create object")
            return super(Foo, cls).__new__(cls)
    def __init__(self, obj):
        if self is obj:
            print("init: same object")
        else:
            print("init: brand new object from ", obj)
            # do the actual initialization

它按预期给出:

>>> foo = Foo("x")
New: create object
init: brand new object from  x
>>> bar = Foo(foo)
New: same object
init: same object
>>> bar is foo
True
点赞