我有一个类,可以在事件发生时将数据预加载到缓存中。我想使用装饰器和事件键注册加载器函数,以便当事件触发时,我可以执行这些函数。
from collections import defaultdict
class Preloader:
def __init__(self):
self.events = defaultdict(set)
def register(self, event_key: str):
print(f"Registering event: `{event_key}`")
def decorator(func):
print("Decorating function: ", func.__qualname__)
def wrapper(*args, **kwargs):
print("Wrapper called...")
# call func, add results to cache, return results
return func(*args, **kwargs)
self.events[event_key].add(wrapper)
return wrapper
return decorator
def preload(self, event_key: str, *args, **kwargs):
for func in self.events[event_key]:
func(*args, **kwargs)
然后我用
register
方法装饰函数。
preloader = Preloader()
class Product:
@staticmethod
@preloader.register("products")
def get_products_static():
# there would really be a database call here
print("Getting products from static method...")
@classmethod
@preloader.register("products")
def get_products_cls(cls):
# there would really be a database call here
print("Getting products from class method...")
当我调用
preloader.preload('products')
时,类方法调用失败并显示
TypeError: Product.get_products_cls() missing 1 required positional argument: 'cls'
如何修改我的装饰器以接受类和实例方法?
选择类/实例的功能怎么样
def preload(self, event_key: str, *args, **kwargs):
for func in self.events[event_key]:
# Check if the function is a class method or instance method
if isinstance(func, types.MethodType): # Check if it's a method
# Rebind 'self' or 'cls' if needed when invoking the function
bound_func = types.MethodType(func.__func__, args[0])
bound_func(*args, **kwargs)
else:
# Directly call the function if it's static
func(*args, **kwargs)