【问题标题】:Python Decorator not performing taskPython装饰器不执行任务
【发布时间】:2013-08-21 01:46:55
【问题描述】:

我的 API 中有以下方法,我想让 serve 函数成为装饰器,以便可以像这样使用它:@api.serve

def add_rule(self, func, methods):    
    for item in methods:
        if item in self._config["MAP"]:
            raise RuntimeError("Cannot override functions.")
        self._config["MAP"][item] = func

def serve(self, methods=["POST","GET","HEAD"]):
    def wrapper(func):
        self.add_rule(func, methods)
        return func

    return wrapper

但是,一切似乎都不起作用,即在 _config["MAP"] 字典中设置项目。没有错误,但它没有做它应该做的事情。有人可以帮帮我吗?

【问题讨论】:

  • 我认为您对self 的引用可能有问题,请参阅stackoverflow.com/questions/1263451/…
  • 要使您的代码正常工作,您需要使用@api.serve();注意添加的括号。您必须调用serve,然后返回wrapper,然后用于装饰函数。如果没有括号,则将修饰函数替换为 wrapper 函数的(损坏的)变体。
  • 不,当我使用非装饰器版本时,它实际上工作得很好:做api.add_rule(serve, ["POST"]) 给我{'POST': <function serve at 0x1017969e0>},但我需要制作它的装饰器版本。
  • @l4mpi 哦,我明白了...谢谢!但是为什么我必须使用括号呢?
  • @Eugene 您是否从其他地方获得此代码?您要使用的实际装饰器是wrapper 函数;这是由调用 serve返回的。在这种情况下,它很有用,因为您可以更改 methods 列表以防您不想要默认值;例如@api.serve(["GET"]) 产生一个只注册 GET 方法的装饰器。

标签: python decorator


【解决方案1】:

1) 你的serve 函数看起来不像装饰器。 你应该这样做... 在你的类定义之外写这个函数。

def serve(func):
    def wrapper(*args,**kwargs):
        func(*agrs,**kwargs) 
    return wrapper

2) 你也可以这样做。

def serve(self,func):
    def wrapper(self,*args,**kwargs):
        func(self,*args,**kwargs)
    return wrapper

您应该在 func 方法定义中调用您的 add_rule 方法。

【讨论】:

  • 是的,你的装饰器是无操作的。此外,您完全错过了 OP 试图做的事情。此外,您还缺少)。 OP 代码怎么看起来不像装饰器?它返回一个函数...
  • thnx @l4mpi 进行更正.. 你问那个代码怎么看起来不像装饰器?因为该函数不返回作为参数传递的函数的包装器,所以不必返回函数,而是返回作为参数传递的函数。看到这个链接..stackoverflow.com/questions/739654/…
  • 我知道装饰器是如何工作的,谢谢。但你似乎很困惑。 OP 使用装饰器在地图中注册函数的副作用,他对用任何东西包装函数不感兴趣。所以只返回原始函数是完全合理的......仅仅因为装饰器通常用于函数包装器并不意味着你不能用它们做其他好事。关于您提议的装饰器,它什么都不做,因此没用;并且您的整个答案完全错过了OP想要做的事情。
  • @tailor_raj:在调用 func(..) 之前添加 self.add_rule(func, methods)。
  • 没有。他调用serve,它返回实际的装饰器(wrapper 函数)。然后wrapper 将一些关于func 的数据添加到他的地图中,然后返回原函数不变。无论如何,装饰器只是函数调用和赋值的语法糖;在 OP 的情况下,他纯粹将其用于函数调用的副作用。
猜你喜欢
  • 2016-07-25
  • 2012-01-20
  • 2019-02-09
  • 2023-03-04
  • 2015-02-05
  • 1970-01-01
  • 2017-08-20
  • 2021-12-15
相关资源
最近更新 更多