__init__没有自我参数的函数定义

Ste*_*ley 18 python

在挖掘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)

稍后在同一个类中,updatesubtract方法也以相同的方式定义.

在你向我指出有关self课程如何运作的问题之前,我会注意到我不相信这是一个重复的问题.我理解self通常self是如何工作的,而不是关键字(只是标准实践)等.我也理解这段代码是有效的(我不是在质疑*unpack/explode/starred-expressions语法的有效性)

我的问题与为什么......

  • 为什么要实现这样的类的__init__其他正常(非@static/ @class方法),以及在未来应该考虑在什么情况下使用它?
  • 为什么只有同一类的特定方法实现如此?
  • 在什么情况下调用这些方法没有任何args(如果有的话),触发第一个TypeError?
  • 在什么情况下可以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并忘记传递selfCounter.__init__(或使用super).

  • @StephenCowley:[描述符协议](https://docs.python.org/3/reference/datamodel.html#descriptors)是方法用于在实例上访问时自动绑定`self`参数的协议.它不仅仅是有用的,但这就是使用它的方法.用于大多数C方法的描述符类型说"如果在没有`self`位置参数的情况下调用,则'type_name'的描述符'method_name'需要一个参数". (2认同)