当我在
Python类中修饰绑定方法时,我需要在外部类的装饰器中获取一些信息.那可能吗?
例如:
def modifier(func):
import sys
cls_namespace = sys._getframe(1).f_locals
cls_namespace['data'] # dictonary has no key 'data'
...
return func
class Parent:
data = "Hi!"
class Child(Parent):
@modifier
def method(self):
pass
cls_namespace只是当前类的不完整命名空间,没有我需要获取的数据字段.
有没有办法在装饰器中获得它?
最佳答案 函数修饰在执行类主体时发生,此时对类本身或其基类一无所知.这意味着修饰符修饰未绑定的函数对象,并且只有在实例上实际调用func时才会绑定它.
您可以返回一个包装函数来替换已修饰的函数,它将被绑定,您将可以访问self:
from functools import wraps
def modifier(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
# self is an instance of the class
self.data
return func(self, *args, **kwargs)
return wrapper
每次在实例上调用方法时,都会调用包装器.
如果必须在创建类时有权访问基类,则必须等到类Child语句完成执行.在Python 3.6之前,这只能来自类装饰器或元类;在创建类主体之后调用每个类,并且您将可以访问(至少)基类.
使用类装饰器,例如:
def modifier(cls):
# cls is the newly created class object, including class attributes
cls.data
return cls
@modifier
class Child(Parent):
def method(self):
pass
现在请注意装饰器的位置.
Python 3.6添加了一个__init_subclass__
method,它也可以为您提供访问权限;每次为当前类创建子类时,都会调用(class)方法:
class Parent:
def __init_subclass__(cls, **kwargs):
# cls is a subclass of Parent
super().__init_subclass__(**kwargs)
cls.data
data = "Hi!"
class Child(Parent):
def method(self):
pass