python 的一大优点是它的交互式解释器。当你写这样的代码时:
>>> def assign(self, input=None, output=None, param=None, p1=None, p2=None):
... pass
...
很容易弄清楚你应该如何使用这个功能:
>>> help(assign)
Python Library Documentation: function assign in module __main__
assign(self, input=None, output=None, param=None, p1=None, p2=None)
通过对比:
>>> def assign2(self, **kwargs):
... pass
...
给出:
>>> help(assign2)
Python Library Documentation: function assign2 in module __main__
assign2(self, **kwargs)
我希望你明白为什么第一种形式更可取。但是您仍然希望避免将所有内容写两次(在参数和正文中)。
第一个问题是你为什么要编写这种性质的代码?我发现这是一个非常常见的情况,我想要一个带有一堆属性的类,它将携带,但这些属性的集合基本上是固定的。在最常见的情况下,这些属性在对象的生命周期内永远不会改变;在这种情况下,python 有一个内置的帮助器!
>>> import collections
>>> Assignment = collections.namedtuple('Assignment', 'input output param p1 p2')
>>> assign = Assignment(None, None, None, None, None)._replace
>>> assign(p1=10)
Assignment(input=None, output=None, param=None, p1=10, p2=None)
>>> help(Assignment)
Python Library Documentation: class Assignment in module __main__
class Assignment(__builtin__.tuple)
| Assignment(input, output, param, p1, p2)
|
... SNIP
namedtuple
是常规类,您可以从它们继承以赋予它们特殊的行为。不幸的是,它们是不可变的,如果您碰巧需要它,您将需要另一种技术;但是您几乎总是应该首先找到命名元组。否则,我们可以使用其他魔法;我们可以得到所有的局部变量,它们在函数开始时只包含参数:
>>> class Assignable(object):
... def assign(self, input=None, output=None, param=None, p1=None, p2=None):
... _kwargs = vars()
... _kwargs.pop('self')
... vars(self).update((attr, value) for attr, value in _kwargs.items() if value is not None)
...
>>> a = Assignable()
>>> vars(a)
{}
>>> a.assign(p1=6)
>>> vars(a)
{'p1': 6}
>>> a.p1
6
而且help()
文字还是很有帮助的!
>>> help(a.assign)
Python Library Documentation: method assign in module __main__
assign(self, input=None, output=None, param=None, p1=None, p2=None) method of __main__.Assignable instance