Python instancemethods & decorators
我有以下问题:
我需要编写一个能够检测在方法和常规函数周围使用它的情况的修饰符。
因此,让我们考虑下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | def somedecorator(fn): print"decorating function:", fn print"function class:", fn.__class__ return fn @somedecorator def regular_func(): print"I'm a regular function" class SomeClass(object): @somedecorator def class_method(self): print"I'm a class method" |
输出为:
1 2 3 4 | decorating function: <function regular_func at 0x181d398> function class: <type 'function'> decorating function: <function class_method at 0x181d410> function class: <type 'function'> |
号
但是,写信:
1 2 3 | print regular_func print SomeClass.class_method print SomeClass().class_method |
产生输出:
1 2 3 | <function regular_func at 0x181d398> <unbound method SomeClass.class_method> <bound method SomeClass.class_method of <__main__.SomeClass object at 0x16d9e50>> |
。
因此,事实证明(并不奇怪)装饰器在被转化为方法之前就被应用于函数。
问题:从装饰师的角度来看,您建议如何区分这两个应用程序?
编辑对于好奇的人-我需要描述的区别,因为腌渍。我真的不想谈这个的细节。
可能正在查看堆栈?
1 2 3 4 5 6 | def somedecorator(fn): import traceback print"decorating function:", fn print"function class:", fn.__class__ print traceback.extract_stack()[-2][2] return fn |
如果从模块输出"module"调用了decorator,则从方法输出"someClass"。如果从函数内部调用,也会返回函数名,因此要区分这两种情况,可以查找locals()和globals(),以了解这些名称到底是什么:函数或类。
你怎么认为?
编辑:对象可能不在作用域内,所以globals()和locals()不能工作…
不能。方法是函数。在这个类中,只有一个正则函数。InstanceMethod描述符魔术只在对象被声明时发生,并且描述符是对象的一部分,而不是类的一部分。"未绑定的方法(btw在python 3中消失了,这是有充分理由的——它们毫无用处,是一个毫无意义的概念,并且增加了一些开销)只是这些函数周围的临时包装器对象,每当函数作为类的属性被访问时都会生成这些对象。
区分方法和函数的最明智的方法是提供两个修饰符,让程序员决定应用哪一个。或者更好的是,不要使用这种奇怪的分离——方法是函数,没有什么特别的,您应该这样对待它们。