这是我实际问题的简化示例。
我在foo
:
foo.py
class foo(object):
def __init__(self):
pass
def bar(self):
return True
@property
def baz(self):
return False
现在,我想使用inspect
模块来获取foo
类的方法(包括baz
)。这是我到目前为止getmethods.py
:
import foo
import inspect
classes = inspect.getmembers(foo, inspect.isclass)
for cls in classes:
methods = inspect.getmembers(cls[1], inspect.ismethod)
print methods
当我运行此脚本时,我得到以下输出(这并非完全出乎意料):
[('__init__', <unbound method foo.__init__>), ('bar', <unbound method foo.bar>)]
所以,我的问题是,为什么baz
不被视为一种方法,如何修改getmethods.py
以获得以下输出:
[('__init__', <unbound method foo.__init__>), ('bar', <unbound method foo.bar>), ('baz', <property object at 0x7fbc1a73d260>)]
答案 0 :(得分:10)
@property
装饰器生成property
对象,而不是函数或方法。正是这个对象在访问时(通过descriptor protocol)调用它在该对象的.fget
,.fset
和.fdel
属性中存储的函数。
您必须明确测试该对象类型:
methods = inspect.getmembers(cls[1], inspect.ismethod)
properties = inspect.getmembers(cls[1], lambda o: isinstance(o, property))
或
methods_and_properties = inspect.getmembers(
cls[1], lambda o: isinstance(o, (property, types.MethodType)))
请注意,同样的限制适用于classmethod
和staticmethod
个对象。