Python:将方法作为函数参数传递时出现属性错误

Python:将方法作为函数参数传递时出现属性错误,python,oop,python-2.7,functional-programming,Python,Oop,Python 2.7,Functional Programming,我确信在堆栈溢出的某个地方会有这个问题的答案,但我一直没有找到答案;它们中的大多数是关于将函数而不是方法作为参数传递给函数的 我目前正在使用Python 2.7.5,并尝试定义如下函数: def func(object, method): object.method() class SomeObject: def some_object_method(self): # do something 如果这样称呼: some_object_instance = So

我确信在堆栈溢出的某个地方会有这个问题的答案,但我一直没有找到答案;它们中的大多数是关于将函数而不是方法作为参数传递给函数的

我目前正在使用Python 2.7.5,并尝试定义如下函数:

def func(object, method):
    object.method()
class SomeObject:
    def some_object_method(self):
        # do something
如果这样称呼:

some_object_instance = SomeObject()
func(some_object_instance, SomeObject.some_object_method)
使用这样定义的类:

def func(object, method):
    object.method()
class SomeObject:
    def some_object_method(self):
        # do something
基本上相当于这样做:

some_object_instance.some_object_method()

一、 然而,不断地得到一个属性错误——类似于

'SomeObject' has no attribute 'method'

我的印象是,我可以合法地将方法作为参数传递,并让它们在以上述方式使用时正确地进行评估。我错过了什么

方法调用不是这样工作的。
foo.bar
语法在
foo
对象上查找名为
bar
的方法。如果您已经有了该方法,只需调用它:

def func(object, method):
    method(object)

func(some_object_instance, SomeObject.some_object_method)
SomeObject.some\u object\u method
是所谓的“未绑定方法”:它是一个没有绑定到
self
的方法对象,因此必须显式地将
self
传递给它

通过一个具体的例子,这可能更有意义:

>>> s = 'ABC'
>>> s_lower = s.lower # bound method
>>> s_lower()
'abc'
>>> str_lower = str.lower # unbound method
>>> str_lower(s)
'abc'

相比之下,
some\u object\u实例。some\u object\u方法
是一个“绑定方法”,您可以按原样调用它,而
some\u object\u实例
已经作为
self
参数“绑定”了:

def func2(method):
    method()
func2(some_object_instance.some_object_method)

未绑定的方法在教程中没有详细解释;它们包含在关于的章节中。因此,您必须查阅参考手册以获取文档(在[standard type hierarchy](),在“用户定义的方法”小节中),这对于新手来说可能有点让人望而生畏



就我个人而言,直到我学会了如何在封面下工作,我才真正明白这一点。大约一年前,我写了一篇博文试图向其他人解释它(但用Python3.x术语,这有点不同);这可能会有帮助。要真正理解它,您必须通过,在交互解释器真正单击之前,可能需要进行一些通读和在交互解释器中进行大量操作,但希望您能够在到达这一点之前理解方法背后的基本概念。

因为您正在向函数传递一个未绑定的方法,您需要将其称为:

method(object)
或者最好将方法的名称作为字符串传递,然后使用
getattr

getattr(object, method)()

为什么按名称而不是通常的“更好”传递它?@abarnert,因为在这种情况下,我们直接处理实例的方法。在第一种情况下,我们必须确保传递与实例完全相同的类,传递基类的未绑定方法将不起作用;如果要调用基类的方法,也可以这样做。他们都是合法的,这只是你想要的。如果要确保调用
对象
自己的
方法
,则传递的是绑定方法,而不是未绑定方法加对象或字符串加对象。我不知道调用绑定方法与未绑定方法之间的区别。它起作用了,但我觉得我应该进一步研究这个问题。谢谢@奥斯汀·舍伦:就我个人而言,直到我学会了如何在封面下工作,我才真正明白这一点。大约一年前,我写了一篇博文试图向其他人解释它(但用Python3.x术语,这有点不同);这可能对你有帮助。