gpt4 book ai didi

python - 绑定(bind)方法上的装饰器可以访问类及其祖先

转载 作者:太空宇宙 更新时间:2023-11-03 12:56:27 24 4
gpt4 key购买 nike

当我装饰 Python 类中的绑定(bind)方法时,我需要从外部类中获取此装饰器中的一些信息。这可能吗?

例如:

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 字段。

有没有办法在装饰器中得到它?

最佳答案

函数修饰发生在类主体被执行时,此时类本身及其基类一无所知。这意味着 modifier 装饰了未绑定(bind)的函数对象,并且只有当 func 在实例上实际调用时才会绑定(bind)它。

您可以返回一个包装函数来替换装饰函数,它将被绑定(bind),您将可以访问 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 语句完成执行。在 Python 3.6 之前,这只能通过类装饰器或元类实现; each 在创建类主体后调用,您将可以访问(至少)基类。

使用类装饰器,例如:

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

关于python - 绑定(bind)方法上的装饰器可以访问类及其祖先,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39698045/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com