2015-12-28 2 views
3

Это упрощенный пример моей реальной проблемы.python inspect get методы, украшенные @property

У меня есть класс 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

ОК, поэтому я опубликовал немного слишком рано, но я по-прежнему ищу хорошую причину, почему свойства не рассматриваются методами, поскольку код выполняется при запросе свойства. На данный момент я выполняю 'методы = inspect.getmembers (cls [1], lambda x: inspect.ismethod (x) или isinstance (x, свойство))' Мне также интересно, есть ли лучший способ. – iLoveTux

ответ

5

@property декор ator создает объект property, а не функцию или метод. Именно этот объект вызывает функцию, которую он сохранил в атрибутах .fget, .fset и .fdel на этом объекте при доступе (через descriptor protocol).

Вы должны явно проверить для этого типа объекта:

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 объектов.

+0

Отличный ответ, забыл о возможности передать кепку на 'isinstance'. – iLoveTux

Смежные вопросы