【问题标题】:Cython does not work with double decorators with argument. Is there a workaround?Cython 不适用于带参数的双装饰器。有解决方法吗?
【发布时间】:2019-05-10 16:40:50
【问题描述】:

我在对我的 python 代码进行 cythonizing 时遇到问题。我试图重现我遇到的最简单的错误情况。

这是我想要cythonize的代码的插图:

     def some_decorator_with_arg(arg):
         def decorator(func):
             def wrapper(x):
                 return func(x) + arg
             return wrapper
         return decorator
 
     class some_class():
         def __init__(self):
             pass
 
         @staticmethod
         @some_decorator_with_arg(1)
         def some_method(a):
             return a
    print(some_class().some_method(1))        

这在纯 python 中没有问题。但是当我对这段代码进行cythonize时,它会在运行时引发错误:

打印(some_class().some_method(1))

TypeError: wrapper() 只接受一个参数(给定 2 个)

编译运行没有问题。如果我写@some_decorator_with_arg(arg=1) 我会得到另一个错误:

@some_decorator_with_arg(arg=1)

TypeError: some_decorator_with_arg() 没有关键字参数

有人知道解决这个问题的方法吗?

【问题讨论】:

标签: python cython python-decorators cythonize


【解决方案1】:

我找到了解决问题的最简单方法——将两个(或多个)装饰器的功能合二为一,那么 cython 就没有问题了。例如,对于上述情况,我会执行以下操作:

def some_decorator_with_arg(arg):
     def decorator(func):
         def wrapper(x):
             return func(x) + arg
         return wrapper
     return decorator

#combine the created decorator with the staticmethod functionality
def staticmethod_combined(*args,**kwargs):
    return lambda func: staticmethod(some_decorator_with_arg(*args,**kwargs)(func))

class some_class():
     def __init__(self):
         pass

     @staticmethod_combined(1)
     def some_method(a):
         return a

print(some_class().some_method(1))        

可以通过在cythonizing时提供标志来解决关键字参数的问题always_allow_keywords=True

【讨论】:

    猜你喜欢
    • 2023-03-29
    • 2016-06-30
    • 2012-03-14
    • 2014-07-21
    • 2014-10-08
    • 2011-09-01
    相关资源
    最近更新 更多