在挖掘python Counter类时collections,我发现了一些我认为特殊的东西:它们没有self在__init__函数的参数中明确使用参数.
请参阅下面的代码(直接复制而不使用docstring):
class Counter(dict):
def __init__(*args, **kwds):
if not args:
raise TypeError("descriptor '__init__' of 'Counter' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 argments, got %d' % len(args))
super(Counter, self).__init__()
self.update(*args, **kwds)
Run Code Online (Sandbox Code Playgroud)
稍后在同一个类中,update和subtract方法也以相同的方式定义.
在你向我指出有关self课程如何运作的问题之前,我会注意到我不相信这是一个重复的问题.我理解self通常self是如何工作的,而不是关键字(只是标准实践)等.我也理解这段代码是有效的(我不是在质疑*unpack/explode/starred-expressions语法的有效性)
我的问题与为什么......
__init__其他正常(非@static/ @class方法),以及在未来应该考虑在什么情况下使用它?self手动填写这些方法(例如Counter.__init__(some_counter))?还是其他例子?我不得不认为它与TypeError("描述符......")有关.
use*_*ica 18
此代码旨在使self位置无.否则,就像一个电话
d = {'self': 5}
Counter(**d)
Run Code Online (Sandbox Code Playgroud)
因为__init__收到两个值而失败self.
大多数类不需要像这种特殊处理那样的东西,但是Counter应该处理关键字参数,就像dict它们一样,它们成为结果映射的关键,即使密钥是'self'.Counter具有此处理的其他方法是需要相同关键字参数行为的方法.
如果您需要self在自己的代码中将其视为有效的关键字参数,则应该执行类似的操作.
至于TypeError那里,那里匹配错误信息来自dict.__init__:
>>> dict.__init__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: descriptor '__init__' of 'dict' object needs an argument
>>> Counter.__init__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.7/collections/__init__.py", line 560, in __init__
raise TypeError("descriptor '__init__' of 'Counter' object "
TypeError: descriptor '__init__' of 'Counter' object needs an argument
Run Code Online (Sandbox Code Playgroud)
在实践中出现这种情况的最可能方式可能是人们继承Counter并忘记传递self给Counter.__init__(或使用super).