有权访问类及其祖先的绑定方法的装饰器

2024-06-06 14:57:29 发布

您现在位置:Python中文网/ 问答频道 /正文

当我在Python类中修饰bound方法时,我需要从外部类获取这个decorator中的一些信息。有可能吗?在

例如:

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只是当前类的不完整名称空间,没有我需要获取的data字段。在

有没有办法在装饰店买到?在


Tags: 方法import信息datadefsysdecoratornamespace
3条回答

这是一个特别均衡的解决方案:

def wrap_class(cls):
    """Wrap a class to allow binding all decorated methods."""
    for func in cls.__dict__.values():
        if hasattr(func, '__wrapped__'):
            func.__wrapped__.im_class = cls

    return cls

{{{然后用cd2}修饰。在

装饰器示例:

^{pr2}$

使用示例:

@wrap_class
class Badger:
    @decorator
    def stoat(self, mushroom, snake):
        pass

Badger().stoat()
Badger.stoat.extra()

函数修饰发生在类主体被执行时,此时对类本身或其基类一无所知。这意味着modifier修饰未绑定函数对象,只有在实例上实际调用了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

然后,每次对实例调用method时都将调用包装器。在

如果必须在类创建时访问基类,则必须等到class Child语句已完成执行。在Python3.6之前,这只能从类修饰符或元类实现;每个类都是在类主体创建之后调用的,并且您至少可以访问基类。在

使用类修饰符,例如:

^{pr2}$

现在记下装饰工的位置。在

Python3.6添加了一个^{} 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

并不是说传递给decorator包装器的第一个参数将是一个objects实例(self)。多亏了它,你可以获得你需要的一切。在

见Raphaels回复: Related issue

def wrapped(self, *f_args, **f_kwargs):

自我是第一个论据

相关问题 更多 >