这是我的代码snappt:
class C(dict):
def __init__(*args, **kwds):
print 'args = {}'.format(args)
print 'kwds = {}'.format(kwds)
if not args:
raise TypeError("descriptor '__init__' of 'Counter' object needs an argument")
self = args[0]
args = args[1:]
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
super(C, self).__init__()
if __name__ == '__main__':
c = C()
当我运行此代码时,我对输出感到困惑:
C:\Users\elqstux\Desktop>python wy.py
args = ({},)
kwds = {}
对于c = C()
,我认为代码会引发错误,因为在这种情况下args
将是()
,但是从输出中args
是{{1} ,是什么原因?
({},)
答案 0 :(得分:6)
*args
为({},)
,因为您没有声明明确的self
参数。因此,当调用__init__
时,self
参数最终成为args
中的第一个元素。由于您从dict
继承,因此dict
的{{1}}为repr
。
此技巧现在在Python的{}
子类中有意使用,因为否则用dict
初始化dict
子类的代码会破坏初始化程序。解决方法是:
mydict(self=123)
迫使 def __init__(*args, **kwargs):
self, *args = args
# On Python 2 without unpacking generalizations you'd use the more repetitive:
# self, args = args[0], args[1:]
纯粹作为位置参数被接受(由实例构造机制隐式传递)。有关实际使用情况的示例,请参阅the implementation of collections.Counter
。
答案 1 :(得分:3)
我对你的输出很感兴趣!原因很清楚:您从self
函数定义中省略了__init__
。使用常规类运行示例将清楚地说明发生了什么:
>>> class C():
... def __init__(*args, **kwargs):
... print args, kwargs
...
>>> C()
(<__main__.C instance at 0x103152368>,) {}
<__main__.C instance at 0x103152368>
当然,self
被args
作为args
元组的单个元素。毕竟,self
就像任何其他论点一样。
在你的情况下让你更加困惑的是,由于你已经将dict
子类化了,所以此时你班级的repr()
为{}
,即repr()
空的dict。因此({},)
。
答案 2 :(得分:1)
使用单个参数调用类__init__
函数,隐式self
参数(即正在创建的新类实例)。通常这会打印为类实例。但是因为类子类dict
,它打印为dict
,最初没有元素。