【问题标题】:Do commit after method execution - decorator在方法执行后提交 - 装饰器
【发布时间】:2015-10-23 00:11:23
【问题描述】:

我是装饰器的新手,我正在尝试创建一个,在方法执行后执行self.commit()

我的论点有问题。方法 commit(装饰器)在类内部。

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() takes exactly 2 arguments (1 given)

我确实知道错误正在引发,因为它不是静态方法,所以我尝试在那里输入self 参数,但仍然出现错误。

你知道问题出在哪里吗?

【问题讨论】:

    标签: python wrapper decorator


    【解决方案1】:

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

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

    更新:

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

    希望这会有所帮助:)

    【讨论】:

    • 谢谢,但是现在应该是静态方法吧?还是我应该把它放在课堂之外?它告诉 commit 应该有 self 参数。
    • @Milan:查看我更新的答案或 a_guest 答案。不,这可能是正常的方法。
    • self 只是将名称绑定到变量(很可能是您要引用的实例)。通常,它用于调用实例方法的实例。当然,self 也可以在其他情况下使用。
    • @a_guest: 是的,你是绝对正确的 :) 但是,最好将 args**kwargs 作为包装器的参数,然后它可以接受任意数量的参数和关键字参数。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      正如之前的帖子所说,您需要为函数传递参数。但是你很可能不想限制你的函数在装饰器中接受的参数,为此使用*args**kwargs。最后,使用functools.wraps 保留原始函数元数据是个好主意。

      完整示例:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-04
        • 2023-03-04
        • 2016-12-14
        • 1970-01-01
        • 1970-01-01
        • 2011-09-07
        • 2020-01-11
        • 2020-07-22
        相关资源
        最近更新 更多