调用 class 的构造函数作为其他 class 构造函数中的默认参数
Calling constructor of class as default argument in other class constructor
问题
我试图在另一个 class' 构造函数参数的默认赋值中调用 class 的构造函数,但我遇到了构造函数未被正确调用的问题。这里发生了什么?
代码解释
Bad
class 是行不通的情况,而 Good
class 是解决问题的丑陋变通方法。每次调用构造函数 Base.__init__
时,值 Base.i
都会递增,可以看出,对于 o2
对象,它没有正确递增,但似乎正确递增对于每个 o1
、o3
和 o4
.
代码
class Base:
i = 0
def __init__(self):
Base.i += 1
self.i = Base.i
class Bad:
def __init__(self, base = Base()):
self.base = base
class Good:
def __init__(self, base = None):
if base is None:
self.base = Base()
else:
self.base = base
if __name__ == "__main__":
o1 = Bad()
o2 = Bad()
print("Bad:")
print(f"o1.i: {o1.base.i}")
print(f"o2.i: {o2.base.i}")
o3 = Good()
o4 = Good()
print("Good:")
print(f"o3.i: {o3.base.i}")
print(f"o4.i: {o4.base.i}")
产出
o1.i: 1
o2.i: 1
Good:
o3.i: 2
o4.i: 3
默认参数在定义时间计算,所以这里
class Bad:
def __init__(self, base = Base()):
self.base = base
名称 base
(因此 self.base
)在定义时已经分配了一个 Base
的实例。
一种方法是使用默认值 None
,正如您在 class Good
中所做的那样
class Good:
def __init__(self, base = None):
if base is None:
self.base = Base()
else:
self.base = base
您还可以像这样定义 Bad
的 __init__
:
class Bad:
def __init__(self, base = Base):
self.base = base()
这将在初始化 Bad
时分配 Base
的实例,而不是在定义时,因此 Bad
的每个实例都会有自己的 Base
。
如果你想将参数传递给 base,你必须添加选项
class Bad:
def __init__(self, base = Base, base_args=(,), base_kwargs={}):
self.base = base(*base_args, **base_kwargs)
但在那种情况下 None
方法更易于使用,因为您可以直接传递构造的实例。
问题
我试图在另一个 class' 构造函数参数的默认赋值中调用 class 的构造函数,但我遇到了构造函数未被正确调用的问题。这里发生了什么?
代码解释
Bad
class 是行不通的情况,而 Good
class 是解决问题的丑陋变通方法。每次调用构造函数 Base.__init__
时,值 Base.i
都会递增,可以看出,对于 o2
对象,它没有正确递增,但似乎正确递增对于每个 o1
、o3
和 o4
.
代码
class Base:
i = 0
def __init__(self):
Base.i += 1
self.i = Base.i
class Bad:
def __init__(self, base = Base()):
self.base = base
class Good:
def __init__(self, base = None):
if base is None:
self.base = Base()
else:
self.base = base
if __name__ == "__main__":
o1 = Bad()
o2 = Bad()
print("Bad:")
print(f"o1.i: {o1.base.i}")
print(f"o2.i: {o2.base.i}")
o3 = Good()
o4 = Good()
print("Good:")
print(f"o3.i: {o3.base.i}")
print(f"o4.i: {o4.base.i}")
产出
o1.i: 1
o2.i: 1
Good:
o3.i: 2
o4.i: 3
默认参数在定义时间计算,所以这里
class Bad:
def __init__(self, base = Base()):
self.base = base
名称 base
(因此 self.base
)在定义时已经分配了一个 Base
的实例。
一种方法是使用默认值 None
,正如您在 class Good
class Good:
def __init__(self, base = None):
if base is None:
self.base = Base()
else:
self.base = base
您还可以像这样定义 Bad
的 __init__
:
class Bad:
def __init__(self, base = Base):
self.base = base()
这将在初始化 Bad
时分配 Base
的实例,而不是在定义时,因此 Bad
的每个实例都会有自己的 Base
。
如果你想将参数传递给 base,你必须添加选项
class Bad:
def __init__(self, base = Base, base_args=(,), base_kwargs={}):
self.base = base(*base_args, **base_kwargs)
但在那种情况下 None
方法更易于使用,因为您可以直接传递构造的实例。