重写没有inspect模块的Python函数
我该如何编写这个自省函数,而不使用inspect模块呢?
import inspect
def trace(cls):
for name, m in inspect.getmembers(cls, inspect.ismethod):
setattr(cls,name,log(m))
return cls
上面的内容来自于 这个StackOverflow的问题/答案
编辑/澄清:有没有可能在不导入任何模块的情况下做到这一点?
请注意,这并不是一个真实的使用案例,而只是出于我个人的好奇心。
3 个回答
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')
,这样就会排除静态方法。
如果我们想要排除类方法,只获取实例方法,我现在知道的唯一解决办法(不需要导入其他模块)就是修改装饰器,检查第一个参数是类还是实例,这样可以帮助你判断被装饰的方法是类方法还是实例方法。
希望这能帮到你 :)
2
大概是这样的:
>>> class Tester(object):
... def mymethod(self):
... return True
...
>>> hasattr(Tester, 'mymethod')
True
>>> hasattr(Tester.mymethod, 'im_func')
True
在Python的文档中,关于数据模型的部分,往下滚动一点就能找到“用户定义的方法”。
一些特殊的只读属性:im_self是类实例对象,im_func是函数对象;im_class是im_self的类,对于绑定方法来说,或者是请求这个方法的类,对于未绑定的方法来说;__doc__是这个方法的文档(和im_func.__doc__是一样的);__name__是方法的名字(和im_func.__name__是一样的);__module__是定义这个方法的模块的名字,如果没有则为None。
从2.6版本开始,im_func和im_self也可以用__func__
和__self__
来表示。我个人比较倾向于使用这些,而不是使用inspect模块。