在没有检查模块的情况下重写python函数

时间:2011-03-30 08:56:29

标签: python reflection introspection

如何在不使用inspect模块的情况下编写此内省函数。

import inspect

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

上述内容来自this SO question/answer

修改/澄清: 是否可以在没有任何进口的情况下这样做?

请注意,这不是一个真实的用例,而是一个纯粹而简单的好奇心案例。

3 个答案:

答案 0 :(得分:2)

类似的东西:

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

data model上的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__提供。 我自己倾向于使用检查模块。

答案 1 :(得分:2)

inspect.ismethod的作用是simply

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

types.MethodTypedefined as

class _C:
   def _m(self): pass
MethodType = type(_C()._m)

答案 2 :(得分:2)

不使用检查我会这样做:

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

修改

你的约束有点奇怪,但请看:

我们可以用if isinstance(attr, types.MethodType)替换if callable(attr)这将只给我们类的可调用属性,其中还包括静态方法和类方法......

我们也可以做其他答案建议使用if hasattr(attr, 'im_func')这将排除静态方法。

如果我们想要排除类方法(只获取实例方法),我认为我现在知道的唯一解决方案(不导入其他模块)是通过更改装饰器来检查第一个参数是否是类或者一个实例,如果要装饰的方法是类或实例方法,这可以给你一个提示。

希望有所帮助:)