gpt4 book ai didi

修改绑定(bind)方法及其类状态的 Python 装饰器

转载 作者:太空宇宙 更新时间:2023-11-04 06:22:16 25 4
gpt4 key购买 nike

我正在尝试编写一个修改其类状态的类方法装饰器。我目前在实现时遇到了麻烦。

附带问题:装饰器何时被调用?它是在实例化类时加载还是在类读取时在读取期间加载?

我想做的是:

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()

我认为在类中手动编写方法列表很丑陋,所以也许装饰器会解决这个问题。

我正在为一个开源项目工作,将 underscore.js 移植到 python。我知道它说我应该只使用 itertools 或其他东西。我这样做只是出于对编程和学习的热爱。顺便说一句,项目托管here

谢谢!

最佳答案

这里有一些问题。

当方法本身被调用时,内部包装器内的任何东西都会被调用。基本上,您是用包装原始函数的函数替换该方法。因此,您的代码在每次调用时都会将方法名称添加到列表中,这可能不是您想要的。相反,该追加应该在 method_wrapper 级别,即在内部包装器之外。这在定义方法时调用,这发生在第一次导入包含该类的模块时。

第二个错误是您从未实际调用该方法——您只是返回它。您应该返回使用提供的参数调用方法的值,而不是 return method - return method(*args, **kwargs)

关于修改绑定(bind)方法及其类状态的 Python 装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11308369/

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