python 检查获取用@property 装饰的方法

Posted

技术标签:

【中文标题】python 检查获取用@property 装饰的方法【英文标题】:python inspect get methods decorated with @property 【发布时间】:2016-04-02 13:56:57 【问题描述】:

这是我实际问题的简化示例。

我在foo.py 中有这样定义的类foo

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>)]

【问题讨论】:

好的,所以我发布的有点太早了,但我仍在寻找一个很好的理由,为什么属性不被视为方法,因为代码是在请求属性时执行的。现在我正在做methods = inspect.getmembers(cls[1], lambda x: inspect.ismethod(x) or isinstance(x, property))我也很好奇是否有更好的方法。 【参考方案1】:

@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)))

请注意,同样的限制适用于 classmethodstaticmethod 对象。

【讨论】:

很好的答案,忘记了能够将元组传递给isinstance

以上是关于python 检查获取用@property 装饰的方法的主要内容,如果未能解决你的问题,请参考以下文章

Python中,关于@property装饰器

Python如何获取用property.setter包装的方法的__qualname__

使用@property

使用@property

二十三Python 中 property() 函数及 @property 装饰器的使用

Python的黑魔法@property装饰器的使用技巧