Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 方法执行后执行提交-装饰器_Python_Wrapper_Decorator - Fatal编程技术网

Python 方法执行后执行提交-装饰器

Python 方法执行后执行提交-装饰器,python,wrapper,decorator,Python,Wrapper,Decorator,我对decorators是新手,我正在尝试创建一个decorators,它在方法执行后执行self.commit() 我对争论有意见。方法commit(decorator)在类内部 def commit(func): def func_wrapper(func): func() self.commit() return func_wrapper 我制定了一个测试方法: @commit def h(self): pass 并称之为:

我对decorators是新手,我正在尝试创建一个decorators,它在方法执行后执行
self.commit()

我对争论有意见。方法commit(decorator)在类内部

def commit(func):
    def func_wrapper(func):
        func()
        self.commit()
    return func_wrapper   
我制定了一个测试方法:

@commit
def h(self):
    pass
并称之为:

db = database()
db.create_tables()
db.h()
错误:
TypeError:commit()只接受2个参数(给定1个)

我确实知道会出现错误,因为它不是一个静态方法,所以我尝试在那里设置
self
参数,但仍然会出现错误


您知道问题出在哪里吗?

您为方法构建装饰器的方式与为函数构建装饰器的方式相同,但是您需要考虑包装器函数的
self

def commit(func):
    def func_wrapper(self):
        func(self)
        self.commit()
    return func_wrapper

更新:

更好的方法是使decorator对函数和方法有用。这可以通过将
*args
**kwargs
作为包装器的参数来实现,因此它可以接受任意数量的参数和关键字参数


希望这有帮助:)

您需要将实际参数传递给包装函数,并使用该参数调用修饰函数:

def commit(func):
    def func_wrapper(self):
        func(self)
        self.commit()
    return func_wrapper

正如前面的文章所说,您需要为函数传递参数。但您很可能不想限制函数在decorator中使用的参数,请使用
*args
**kwargs
。最后,最好使用它来保留原始函数元数据

完整示例:

from functools import wraps

def commit(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        func(self, *args, **kwargs)
        self.commit()
    return wrapper

谢谢,但现在,它应该是一个静态方法?还是我应该把它放在课外?它告诉commit应该有self参数。@Milan:请参阅我的更新答案或一个客户答案。不,这可能是正常的方法。
self
只是将一个名称绑定到一个变量(很可能是您要引用的实例)。通常,它用于调用实例方法的实例。当然,
self
也可以在其他上下文中使用。@a_guest:是的,你完全正确:)但是,最好将
args
**kwargs
作为包装器的参数,然后它可以接受任意数量的参数和关键字参数。