So this code:
所以这段代码:
from inspect import *
class X(object):
def y(self):
pass
methods = getmembers(X, predicate=ismethod)
functions = getmembers(X, predicate=isfunction)
print("%r" % methods)
print("%r" % functions)
From python2.7 yields:
从python2.7收益率:
[('y', <unbound method X.y>)]
[]
and from python3.3 yields:
从python3.3收益率:
[]
[('y', <function X.y at 0x1006ee3b0>)]
I've nosed around, but I can't see any obvious reason for this change in behavior.
我已经知道了,但我看不出有什么明显的理由来改变这种行为。
Specifically, why is python 3 treating my method as a function?
具体来说,为什么python 3把我的方法当作一个函数?
Is there any cross-runtime way of fetching the list of methods on a class?
在类上获取方法列表是否有任何跨运行时的方法?
(ie. something that returns the same when run on both python2.X and 3.X)
(即。当在python2上运行时返回相同的东西。和3. X)
Edit: Example of getmembers() not working:
编辑:getmembers()不工作的示例:
from inspect import *
class X(object):
def y(self):
pass
methods = getmembers(X)
for i in methods:
if ismethod(i):
print("Method: %s" % str(i))
else:
print("Not a method: %s" % str(i))
Prints:
打印:
Not a method: ('__class__', <attribute '__class__' of 'object' objects>)
Not a method: ('__delattr__', <slot wrapper '__delattr__' of 'object' objects>)
Not a method: ('__dict__', <attribute '__dict__' of 'X' objects>)
Not a method: ('__dir__', <method '__dir__' of 'object' objects>)
Not a method: ('__doc__', None)
Not a method: ('__eq__', <slot wrapper '__eq__' of 'object' objects>)
Not a method: ('__format__', <method '__format__' of 'object' objects>)
Not a method: ('__ge__', <slot wrapper '__ge__' of 'object' objects>)
Not a method: ('__getattribute__', <slot wrapper '__getattribute__' of 'object' objects>)
Not a method: ('__gt__', <slot wrapper '__gt__' of 'object' objects>)
Not a method: ('__hash__', <slot wrapper '__hash__' of 'object' objects>)
Not a method: ('__init__', <slot wrapper '__init__' of 'object' objects>)
Not a method: ('__le__', <slot wrapper '__le__' of 'object' objects>)
Not a method: ('__lt__', <slot wrapper '__lt__' of 'object' objects>)
Not a method: ('__module__', '__main__')
Not a method: ('__ne__', <slot wrapper '__ne__' of 'object' objects>)
Not a method: ('__new__', <built-in method __new__ of type object at 0x1001e0640>)
Not a method: ('__reduce__', <method '__reduce__' of 'object' objects>)
Not a method: ('__reduce_ex__', <method '__reduce_ex__' of 'object' objects>)
Not a method: ('__repr__', <slot wrapper '__repr__' of 'object' objects>)
Not a method: ('__setattr__', <slot wrapper '__setattr__' of 'object' objects>)
Not a method: ('__sizeof__', <method '__sizeof__' of 'object' objects>)
Not a method: ('__str__', <slot wrapper '__str__' of 'object' objects>)
Not a method: ('__subclasshook__', <method '__subclasshook__' of 'object' objects>)
Not a method: ('__weakref__', <attribute '__weakref__' of 'X' objects>)
Not a method: ('y', <function X.y at 0x1006ee3b0>)
2 个解决方案
#1
13
Not specifically a difference with inspect
but Python 3 in general see here
与inspect没有特别的区别,但是Python 3在这里可以看到
The concept of “unbound methods” has been removed from the language. When referencing a method as a class attribute, you now get a plain function object.
“未绑定方法”的概念已经从语言中删除。当将方法引用为类属性时,现在将得到一个普通的函数对象。
My suggestion for cross-platform would be:
我对跨平台的建议是:
getmembers(X, predicate=lambda x: isfunction(x) or ismethod(x))
#2
4
Because essentialy there is no difference between a function and an unbound method. This idea of unbound methods exists in Python 2 mostly for historical reasons and was removed in Python 3.
因为本质上,函数和未绑定方法之间没有区别。这种未绑定方法的思想在Python 2中存在,主要是由于历史原因,在Python 3中被删除。
This email by the BDFL himself goes into some details.
这封由伦敦交通局自己写的电子邮件详述了一些细节。
Answering your updated question. I think its best to use inspect.isroutine
as it matches both unbound methods and functions with an additional benefit of also matching methods/functions implemented in C.
回答你的更新问题。我认为最好使用检查。isroutine,因为它同时匹配未绑定的方法和函数,而且还可以匹配在C中实现的方法/函数。
Start with inspect.getmembers
and filter its output as you need. It also takes an optional predicate
parameter.
开始检查。获取成员并根据需要过滤其输出。它还接受一个可选谓词参数。
#1
13
Not specifically a difference with inspect
but Python 3 in general see here
与inspect没有特别的区别,但是Python 3在这里可以看到
The concept of “unbound methods” has been removed from the language. When referencing a method as a class attribute, you now get a plain function object.
“未绑定方法”的概念已经从语言中删除。当将方法引用为类属性时,现在将得到一个普通的函数对象。
My suggestion for cross-platform would be:
我对跨平台的建议是:
getmembers(X, predicate=lambda x: isfunction(x) or ismethod(x))
#2
4
Because essentialy there is no difference between a function and an unbound method. This idea of unbound methods exists in Python 2 mostly for historical reasons and was removed in Python 3.
因为本质上,函数和未绑定方法之间没有区别。这种未绑定方法的思想在Python 2中存在,主要是由于历史原因,在Python 3中被删除。
This email by the BDFL himself goes into some details.
这封由伦敦交通局自己写的电子邮件详述了一些细节。
Answering your updated question. I think its best to use inspect.isroutine
as it matches both unbound methods and functions with an additional benefit of also matching methods/functions implemented in C.
回答你的更新问题。我认为最好使用检查。isroutine,因为它同时匹配未绑定的方法和函数,而且还可以匹配在C中实现的方法/函数。
Start with inspect.getmembers
and filter its output as you need. It also takes an optional predicate
parameter.
开始检查。获取成员并根据需要过滤其输出。它还接受一个可选谓词参数。