使用默认参数清理 pythonic 组合
Clean pythonic composition with default parameters
假设我想组合两个对象,并且我希望能够定义多个遵循默认参数的构造函数。
class A:
def __init__(x,y=0):
self.x = x
self.y = y
class B:
def __init__(w,objA, z=1):
self.w = w
self.objA = objA
self.z = z
我想要 B
的多个构造函数,它们允许我传递对象 A
或传递参数然后构造 A
。看着 What is a clean, pythonic way to have multiple constructors in Python? 我能做到:
class B:
def __init__(w, objA, z=1):
self.w = w
self.objA = objA
self.z=z
@classmethod
def from_values(cls,w,z,x,y):
objA = A(x,y)
return cls(w,objA,z)
问题是默认值被覆盖了,我想保留它们。下面当然不行了。
@classmethod
def from_values(cls,w,x,**kwargs):
objA = A(x,**kwargs)
return cls(w,objA,**kwargs)
所以我似乎一直坚持记住默认值并像这样调用它们
@classmethod
def from_values(cls,w,x,z=1,y=0):
objA = A(x,y)
return cls(w,objA,z)
这不是我想要的,因为我宁愿让对象自己处理默认值,而不是被迫记住默认值。我可以做得比上面更好并使用:
@classmethod
def from_values(cls,w,x,z=1,**kwargs):
objA = A(x,**kwargs)
return cls(w,objA,z)
但在这种情况下,我仍然需要"remember" z
的默认值。对此有 Pythonic 解决方案吗?这是设计问题吗?有人可以指出一个好的设计模式或最佳实践吗?当与多个对象组合时,这个问题会变得复杂...
class L:
def __init__(objM,objN):
self.objM = objM
self.objN = objN
@classmethod
def from_values(cls, m1,m2,m3,n1,n2):
objM = M(m1,m2,m3)
objN = N(n1,n2)
return cls(objM, objN)
首先,我认为这不是您想要做的。随着规模的扩大,尝试调用您的构造函数将变得乏味且容易出错。
你可以用显式字典解决我们的两个问题。
class A:
def __init__(self, config):
self.x = config.get('x')
assert self.x # if you need it
self.y = config.get('y', 0)
class B:
def __init__(self, b_config, objA):
self.w = b_config.get('w')
self.objA = objA
self.z = b_config.get('z', 1)
@classmethod
def from_values(cls,b_config,a_config):
return cls(b_config, A(a_config))
B.from_values({'w':1, 'z':2}, {'x': 3, 'y': 4})
它可能不像您正在寻找的那样聪明或简洁,但它确实允许您从 A
构建,如果您已经拥有它,或者在更结构化的方式。
假设我想组合两个对象,并且我希望能够定义多个遵循默认参数的构造函数。
class A:
def __init__(x,y=0):
self.x = x
self.y = y
class B:
def __init__(w,objA, z=1):
self.w = w
self.objA = objA
self.z = z
我想要 B
的多个构造函数,它们允许我传递对象 A
或传递参数然后构造 A
。看着 What is a clean, pythonic way to have multiple constructors in Python? 我能做到:
class B:
def __init__(w, objA, z=1):
self.w = w
self.objA = objA
self.z=z
@classmethod
def from_values(cls,w,z,x,y):
objA = A(x,y)
return cls(w,objA,z)
问题是默认值被覆盖了,我想保留它们。下面当然不行了。
@classmethod
def from_values(cls,w,x,**kwargs):
objA = A(x,**kwargs)
return cls(w,objA,**kwargs)
所以我似乎一直坚持记住默认值并像这样调用它们
@classmethod
def from_values(cls,w,x,z=1,y=0):
objA = A(x,y)
return cls(w,objA,z)
这不是我想要的,因为我宁愿让对象自己处理默认值,而不是被迫记住默认值。我可以做得比上面更好并使用:
@classmethod
def from_values(cls,w,x,z=1,**kwargs):
objA = A(x,**kwargs)
return cls(w,objA,z)
但在这种情况下,我仍然需要"remember" z
的默认值。对此有 Pythonic 解决方案吗?这是设计问题吗?有人可以指出一个好的设计模式或最佳实践吗?当与多个对象组合时,这个问题会变得复杂...
class L:
def __init__(objM,objN):
self.objM = objM
self.objN = objN
@classmethod
def from_values(cls, m1,m2,m3,n1,n2):
objM = M(m1,m2,m3)
objN = N(n1,n2)
return cls(objM, objN)
首先,我认为这不是您想要做的。随着规模的扩大,尝试调用您的构造函数将变得乏味且容易出错。
你可以用显式字典解决我们的两个问题。
class A:
def __init__(self, config):
self.x = config.get('x')
assert self.x # if you need it
self.y = config.get('y', 0)
class B:
def __init__(self, b_config, objA):
self.w = b_config.get('w')
self.objA = objA
self.z = b_config.get('z', 1)
@classmethod
def from_values(cls,b_config,a_config):
return cls(b_config, A(a_config))
B.from_values({'w':1, 'z':2}, {'x': 3, 'y': 4})
它可能不像您正在寻找的那样聪明或简洁,但它确实允许您从 A
构建,如果您已经拥有它,或者在更结构化的方式。