How to Extend Large Class Methods?
如果要扩展一个类及其各自的
1 2 3 4 5 6 7 8 | 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 |
是否可以缩短子类的
除了删除特定于子类的项之外,您可以执行与引用的答案类似的操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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') |
这导致
1 2 3 4 5 6 7 8 9 10 11 | 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 |
。
注意,在第二个示例中,您丢失了一些功能,因为额外的位置参数不会自动填充关键字参数。您可以通过更多的编码来解决这个问题,或者只接受这些限制。很多使用
做你想做的事没有什么好方法。一般来说,命名所有参数是主要的方法。
不过,有几种方法可能会有所帮助。一种方法是将一些参数绑定到更大的集合中,因此只需要将一个项传递给父类,而不需要将几个项传递给父类。下面是使用一个可重复序列来保存
1 2 3 | def __init__(self, thing_args, ex_arg1, ex_arg2): super().__init__(*thing_args) # ... |
另一种方法是使用
1 2 3 | def __init__(self, ex_arg1, ex_arg2, *args): super().__init__(*args) # ... |
号
调用方需要首先列出
要求将所有内容作为关键字参数传递可能更好,因为调用方可以将关键字参数按最自然的顺序放置:
1 2 3 | def __init__(self, *, ex_args1, ex_args2, **kwargs): super.__init__(self, **kwargs) # passes along the unnamed keyword args # ... |
这种方法最大的缺点是调用会变得相当冗长,其中包含所有参数名:
1 2 | st = SubThing(arg1="foo", arg2="bar", arg3="baz", arg4="quux", ex_arg1=1, ex_arg2=6.02e23) |
。