在__init__参数列表中初始化对象,以返回相同的实例作为默认值。
在__init__参数列表中初始化对象,以返回相同的实例作为默认值。
给定以下示例代码:
class Foo: def __init__(self): return class Bar: def __init__(self, foo = Foo()): print(foo) bar1 = Bar() bar2 = Bar() print(bar1) print(bar2)
输出如下:
<__main__.Foo object at 0x000002A989A2E9B0> <__main__.Foo object at 0x000002A989A2E9B0> <__main__.Bar object at 0x000002A989A2EA20> <__main__.Bar object at 0x000002A989A2EA90>
让两个Foo
实例都是相同的是出乎意料的。我希望每次创建一个Bar()
对象时,都能得到一个独立的Foo
对象。
如何修改我的示例,以便每次调用Bar()
都会创建自己独立的Foo
对象?我需要使用__new__
吗?
在上述代码中,定义了一个名为Foo的类和一个名为Bar的类。Bar类的构造函数__init__有一个参数foo,默认值为None。如果foo的值为None,则将foo赋值为一个新的Foo对象。
问题的原因是,每次实例化Bar类的对象时,会调用__init__函数,如果没有传入foo的值,则会创建一个新的Foo对象。因此,bar1和bar2的foo属性指向不同的Foo对象。
解决方法是在类的定义中,将默认值设为一个可变对象,例如将foo的默认值设为一个空的列表[]。这样,每次实例化Bar类的对象时,如果没有传入foo的值,会使用同一个可变对象作为默认值,从而保证bar1和bar2的foo属性指向同一个对象。
以下是修改后的代码示例:
class Bar: def __init__(self, foo = []): if not foo: foo.append(Foo()) print(foo) bar1 = Bar() bar2 = Bar() print(bar1) print(bar2)
或者使用attr库来解决这个问题,具体的代码如下所示:
import attr class Bar(object): foo = attr.ib(default=attr.Factory(list)) bar1 = Bar() bar2 = Bar() print(bar1.foo) print(bar2.foo)
这样修改后,bar1和bar2的foo属性指向同一个空列表对象。