我遇到了一种蟒蛇般的好奇心,它的含义让我摸不着头脑。
我发现在类中使用字典的方法分派的工作方式不同,这取决于分派是否是在__init__()中完成的。区别在于所选方法是使用self参数调用的还是不使用self参数调用的。
代码说明:
#!/usr/bin/python
class strange(object):
def _eek(): # no self argument
print "Hi!\n"
dsp_dict = {"Get_eek" : _eek}
noideek = dsp_dict["Get_eek"]
def __init__(self):
self.ideek = self.dsp_dict["Get_eek"]
self.ideek2 = self._eek
self.ideek3 = self.noideek
def call_ideek(self):
try:
self.ideek()
except TypeError:
print "Alas!\n"
def call_ideek2(self):
try:
self.ideek2()
except TypeError:
print "Alas!\n"
def call_ideek3(self):
try:
self.ideek3()
except TypeError:
print "Alas!\n"
def call_noideek(self):
try:
self.noideek()
except TypeError:
print "Alas!\n"
x=strange()
print "Method routed through __init__() using the dictionary:"
x.call_ideek()
print "Method routed through __init__() directly:"
x.call_ideek2()
print "Method routed through __init__() using attribute set from dictionary:"
x.call_ideek3()
print "Method not routed through __init__():"
x.call_noideek()运行这段代码,我发现:
I, kazoo > ./curio.py
Method routed through __init__() using the dictionary:
Hi!
Method routed through __init__() directly:
Alas!
Method routed through __init__() using attribute set from dictionary:
Alas!
Method not routed through __init__():
Alas!try-except子句捕捉到了这类事情:
Traceback (most recent call last):
File "./curio.py", line 19, in <module>
x.call_noideek()
TypeError: call_noideek() takes no arguments (1 given)也就是说,如果间接寻址是通过引用字典在__init__中完成的,则不会使用隐式self参数调用产生的方法。
但是,如果在__init__中通过直接引用_eek(),或者通过创建新属性(noideek)并从字典中设置它,或者甚至在__init__中通过引用最初从字典中设置的属性来实现间接寻址,那么self参数就在调用列表中。
我可以使用它,但我不理解它。为什么调用签名会有所不同?
发布于 2017-02-15 08:07:04
看看这个
>>> x.ideek
<function _eek at 0x036AB130>
>>> x.ideek2
<bound method strange._eek of <__main__.strange object at 0x03562C30>>
>>> x.ideek3
<bound method strange._eek of <__main__.strange object at 0x03562C30>>
>>> x.noideek
<bound method strange._eek of <__main__.strange object at 0x03562C30>>
>>> x.dsp_dict
{'Get_eek': <function _eek at 0x036AB130>}
>>> x._eek
<bound method strange._eek of <__main__.strange object at 0x03562C30>>你可以在这里看到静态方法和类方法之间的区别。
当您将类方法存储在该dict中时,它将丢失有关它所包含的类的信息,并被视为一个函数(请参见x.dsp_dict的输出)。
只有当您在类上下文中将该函数分配给noideek方法时,它才会再次成为的类方法。
然而,当从init方法中引用dict时,python会将其作为一个静态方法("function")威胁,不做任何更改,并省略self参数。(ideek)
ideek2和ideek3可以看作是“别名”,其中类方法只被重新引用。
https://stackoverflow.com/questions/42234336
复制相似问题