Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何调用用super()检索的可调用项?_Python_Function_Methods_Super - Fatal编程技术网

Python 如何调用用super()检索的可调用项?

Python 如何调用用super()检索的可调用项?,python,function,methods,super,Python,Function,Methods,Super,我注意到,通过这个B.f实现,调用B.f(B)会引发TypeError: >>A类: ... def f(self):打印('foo') ... >>>B(A)类: ... def f(自我): ... super().f() ... 打印('bar') ... >>>B.f(B())#实例自论证 福 酒吧 >>>B.f(B)#非实例自辩 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“”,第3行,在f中 TypeError:f()

我注意到,通过这个
B.f
实现,调用
B.f(B)
会引发
TypeError

>>A类:
...     def f(self):打印('foo')
... 
>>>B(A)类:
...     def f(自我):
...         super().f()
...         打印('bar')
... 
>>>B.f(B())#实例自论证
福
酒吧
>>>B.f(B)#非实例自辩
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第3行,在f中
TypeError:f()缺少1个必需的位置参数:“self”
但是有了这个
B.f
实现,调用
B.f(B)
工作:

>>A类:
...     def f(self):打印('foo')
... 
>>>B(A)类:
...     def f(自我):
...         if isinstance(self,B):super().f()#绑定方法调用
...         else:super().f(self)#函数调用
...         打印('bar')
... 
>>>B.f(B())#实例自论证
福
酒吧
>>>B.f(B)#非实例自辩
福
酒吧
这是因为
super()

超级(B,B()).f >>>超级(B,B).f
所以我想知道上面的两个
B.f
实现中哪一个是惯用的。换句话说,如果类设计器假定类的函数总是使用作为类实例的
self
参数调用(如第一个
B.f
实现,它总是将
super().f
作为绑定方法调用,即
super().f()
),或者他还应该处理
self
参数不是类*(比如第二个
B.f
实现,它调用
super().f
作为绑定方法,即
super().f()
,或者作为函数,即
super().f(self)
)的情况吗


*这是可能的,因为Python 3.0允许高级使用,如Guido van Rossum:

在Python 3000中,取消了未绑定方法的概念,表达式“A.spam”返回一个普通函数对象。事实证明,第一个参数必须是A实例的限制对诊断问题几乎没有帮助,而且常常是高级用法的障碍——有人称之为“duck typing self”,这似乎是一个合适的名称

我想知道上面的两个B.f实现中哪一个是惯用的

比较简单的是惯用语


我真的看不出一个子类为什么要做
isinstance(self,subclass)
,或者调用者为什么要做
B.f(B)

通常,有实例方法(它们倾向于将
self
作为第一个参数,而没有修饰符)、静态方法(具有
@staticmethod
装饰器)和类方法(具有
@classmethod
装饰器)。您将看到这两个装饰器(staticmethod,classmethod)列为

调用
B().f()
时,由于
B()
是一个实例,因此会将该方法隐式转换为一个函数,该函数的第一个参数是实例,而实例是

另一方面,当调用
B.f()
时,不会发生这种情况;不会插入额外的参数值(也不会解释这一点)。但是,由于方法
f
是用一个没有默认值的参数定义的,因此会出现错误“缺少1个必需的位置参数…”

至于代码约定,您可以添加
isinstance
检查,但通常情况下,代码会假设用户将使用正确的类型或从正确类型的实例调用方法(如果需要);否则用户将遇到错误。这样,您的代码可以保持简单

b=b()
#在以下两个调用中,`B.f`中的`self`标识符将是相同的
b、 f()
B.f(B)#除非标记为静态,否则不会期望用户以这种方式调用'f'
#下面的“B.f”中的“self”标识符是一个类,而不是该类的实例,如上述两种情况所示
#通常,你不会期望用户以这种方式调用'f'。
B.f(B)

我刚刚意识到,通过这个
A.g
实现,这个问题并不特定于使用
super()

>>A类:
…def f(self):打印('foo')
…def g(自我):
…self.f()
…打印('bar'))
... 
>>>A.g(A())
福
酒吧
>>>A.g(A)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第4行,在g中
TypeError:f()缺少1个必需的位置参数:“self”
我们通常不编写这个
A.g
实现:

>>A类:
…def f(self):打印('foo')
…def g(自我):
…如果isinstance(self,A):self.f()#绑定方法调用
…else:self.f(self)#函数调用
…打印('bar'))
... 
>>>A.g(A())
福
酒吧
>>>A.g(A)
福
酒吧

但我们应该这样做吗?我想知道Guido van Rossum所指的非实例优先论点的“高级用法”是什么。

像你一样,我想知道Guido所指的“高级用法”是什么。我想知道Guido所指的“高级用法”是什么。正如我在第二个链接的回答中所说的:一个参数
super()
的ument形式在重要的情况下不起作用,它是在Python 2世界中设计的,已经过时。Guido同意它应该被视为不推荐使用。使用这种形式不是惯用的。@MartijnPieters我认为有点混乱。这篇文章实际上根本不是关于
super()
的单参数形式(它甚至不特定于
super()
,参见下文)。它是关于Guido所指的duck键入
self
的应用程序(
self