我正在尝试编写一个修改其类状态的类方法装饰器。我目前在实施它时遇到麻烦。
附带问题:装饰师什么时候被召唤?它是在类实例化时加载还是在类读取时打开?
我想做的是这样的:
class ObjMeta(object):
methods = []
# This should be a decorator that magically updates the 'methods'
# attribute (or list) of this class that's being read by the proxying
# class below.
def method_wrapper(method):
@functools.wraps(method)
def wrapper(*args, **kwargs):
ObjMeta.methods.append(method.__name__)
return method(*args, **kwargs)
return wrapper
# Our methods
@method_wrapper
def method1(self, *args):
return args
@method_wrapper
def method2(self, *args):
return args
class Obj(object):
klass = None
def __init__(self, object_class=ObjMeta):
self.klass = object_class
self._set_methods(object_class)
# We dynamically load the method proxies that calls to our meta class
# that actually contains the methods. It's actually dependent to the
# meta class' methods attribute that contains a list of names of its
# existing methods. This is where I wanted it to be done automagically with
# the help of decorators
def _set_methods(self, object_class):
for method_name in object_class:
setattr(self, method_name, self._proxy_method(method_name))
# Proxies the method that's being called to our meta class
def _proxy_method(self, method_name):
def wrapper(*fargs, **fkwargs):
return getattr(self.klass(*fargs, **fkwargs), method_name)
return wrapper()
我认为在类中手动编写方法列表很丑陋,所以也许装饰器会解决这个问题。
这是针对我正在工作的一个开源项目,端口强调.js python。我知道它说我应该只使用迭代工具或其他东西。我这样做只是为了热爱编程和学习。顺便说一句,项目托管在这里
谢谢!
这里有一些错误。
调用方法本身时,将调用内部包装器中的任何内容。基本上,您将该方法替换为该函数,该函数包装了原始方法。因此,您的代码每次调用时都会将方法名称添加到列表中,这可能不是您想要的。相反,该追加应该在method_wrapper
级别,即在内部包装器之外。这在定义方法时调用,这在第一次导入包含类的模块时发生。
第二件错误的事情是你从来没有真正调用过该方法 - 你只是返回它。而不是return method
您应该返回使用提供的 args 调用方法的值 - return method(*args, **kwargs)
。