Переписать функцию Python без проверки модуля - PullRequest
2 голосов
/ 30 марта 2011

Как бы я написал эту интроспективную функцию без использования модуля проверки.

import inspect

def trace(cls):
    for name, m in inspect.getmembers(cls, inspect.ismethod):
        setattr(cls,name,log(m))
    return cls

Выше приведено этого SO вопроса / ответа

Редактировать / Уточнить: Возможно ли это сделать и без импорта?

Обратите внимание, что это не реальный случай использования, а чистый и простой случай любопытства с моей стороны.

Ответы [ 3 ]

2 голосов
/ 30 марта 2011

Что inspect.ismethod делает просто :

import types
def ismethod(obj):
   return isinstance(obj, types.MethodType)

и types.MethodType - это , определяемое как :

class _C:
   def _m(self): pass
MethodType = type(_C()._m)
2 голосов
/ 30 марта 2011

Не используя inspect, я сделаю это так:

import types

def trace(cls):
    for attr_name in cls.__dict__:
        attr = getattr(cls, attr_name)
        if isinstance(attr, types.MethodType):
            setattr(cls, attr_name, log(attr))
    return cls

EDIT:

Ваше ограничение немного странно, но давайте посмотрим:

Мы можем заменить if isinstance(attr, types.MethodType) на if callable(attr), что даст нам только вызываемый атрибут класса, который включает также статические методы и методы класса ...

Мы также можем сделать, так как другой ответ предлагает использовать if hasattr(attr, 'im_func'), это исключит статические методы.

Если мы тоже хотим исключить метод класса (только метод экземпляра), я думаю, что единственное решение, о котором я сейчас знаю (без импорта другого модуля), - это изменение декоратора, чтобы проверить, является ли первый аргумент классом или экземпляр, это может дать вам подсказку, если метод, который будет оформлен, является классом или методом экземпляра.

Надеюсь, это поможет:)

2 голосов
/ 30 марта 2011

что-то вроде этого:

>>> class Tester(object):
...   def mymethod(self):
...     return True
... 
>>> hasattr(Tester, 'mymethod')
True
>>> hasattr(Tester.mymethod, 'im_func')
True

из документации по Python в модели данных прокрутите немного вниз, чтобы перейти к "пользовательским методам".

Special read-only attributes: im_self is the class instance object, im_func is the function object; im_class is the class of im_self for bound methods or the class that asked for the method for unbound methods; __doc__ is the method’s documentation (same as im_func.__doc__); __name__ is the method name (same as im_func.__name__); __module__ is the name of the module the method was defined in, or None if unavailable.

im_func и im_self с версии 2.6 также доступны как __func__ и __self__ соответственно.Я здесь склонен тяготеть, чем сам пользоваться модулем проверки.

...