[英]How to Extend Large Class Methods?
如果要扩展一个类及其相应的__init__
方法,是否可以处理包括新参数在内的大量参数? 例如:
class Thing:
def __init__(self, arg1, arg2, arg3, arg4):
# Initialize
class SubThing(Thing):
def __init__(self, arg1, arg2, arg3, arg4, ex_arg1, ex_arg2):
super().__init__(arg1, arg2, arg3, arg4):
# Do extra initialization
是否可以缩短子类的__init__
方法的参数列表? 像这样的回答这一个没有描述如何将参数添加到init,或者如何处理额外的关键字参数,例如__init__(self, arg1, arg_room='Bedroom', ex_arg1, ex_position=(0, 0), ex_arg2)
。
真正没有一种做您想要的事情的好方法。 一般来说,命名所有参数是主要的方法。
有一些方法可能会有所帮助。 一种是将一些参数捆绑到更大的集合中,因此您只需要将一项传递给父类,而不是多项。 使用可迭代序列保存arg1
- arg4
可能看起来像这样,但您可能想改用自定义类(有关将其他类型的多个参数捆绑在一起的类型的示例,请参阅csv
模块中的Dialect
类) :
def __init__(self, thing_args, ex_arg1, ex_arg2):
super().__init__(*thing_args)
# ...
另一种方法是使用*args
和/或**kwargs
接收要传递的参数。 使用位置*args
是相当有限的,因为您必须在传递的所有参数之前列出子类中您关心的参数:
def __init__(self, ex_arg1, ex_arg2, *args):
super().__init__(*args)
# ...
ex_argsN
者将需要首先列出ex_argsN
参数的值,这可能是不自然的。 子类越多,情况就越糟。
要求将所有参数作为关键字参数传递可能会更好,因为调用方可以按最自然的顺序放置关键字参数:
def __init__(self, *, ex_args1, ex_args2, **kwargs):
super.__init__(self, **kwargs) # passes along the unnamed keyword args
# ...
这种方法的最大缺点是,使用所有参数名称的调用变得非常冗长:
st = SubThing(arg1="foo", arg2="bar", arg3="baz", arg4="quux",
ex_arg1=1, ex_arg2=6.02e23)
您可以执行与引用的答案类似的操作,除了删除特定于您的子类的项。
class Thing:
def __init__(self, arg1, arg2, arg3, arg4, kw1=None, kw2=None):
print('Thing args:',arg1,arg2,arg3,arg4)
print('Thing kw:',kw1,kw2)
class SubThing(Thing):
def __init__(self, *args, **kw):
"""SubThing(arg1, arg2, arg3, arg4, arg5, arg6, kw1=None, kw2=None,
kw3=None, kw4=None)
"""
if len(args) != 6:
raise TypeError(
"SubThing() takes 6 positional arguments but {} were given"
.format(len(args)))
arg5, arg6 = args[4:]
kw3 = kw.pop('kw3', None)
kw4 = kw.pop('kw4', None)
super().__init__(*args[:4], **kw)
SubThing(1,2,3,4,5,6,kw1='kw1',kw4='kw4')
print('---- but populating kwargs from positional args stops working ----')
Thing(1,2,3,4, 'kw1', 'kw2')
SubThing(1,2,3,4,5,6,'kw1','kw2')
这导致
Thing args: 1 2 3 4
Thing kw: kw1 None
---- but populating kwargs from positional args stops working ----
Thing args: 1 2 3 4
Thing kw: kw1 kw2
Traceback (most recent call last):
File "n.py", line 24, in <module>
SubThing(1,2,3,4,5,6,'kw1','kw2')
File "n.py", line 14, in __init__
.format(len(args)))
TypeError: SubThing() takes 6 positional arguments but 8 were given
请注意,在第二个示例中,您失去了一些功能,因为多余的位置参数没有自动填充关键字参数。 您可以使用更多编码来解决该问题,也可以接受限制。 许多使用*args, **kw
忘记这样做,因此您的关系很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.