有没有办法对装饰器函数执行 if-else / try- except ?

alv*_*vas 1 python decorator try-except

这个库 X 有两个版本:7 和 8。

在版本 7 中,调用装饰器的回调resultcallback()

在版本 8 中,回调被称为result_callback()

目前我有一个代码可以对 X 库的版本 7 执行类似的操作:

from x import x  # Some sort of decorator library.

@x.resultcallback()
def process_pipeline(func, **kwargs):
    with x.get_stream as fin:
        func(fin)
Run Code Online (Sandbox Code Playgroud)

我的用户只想依赖其中一个版本,但两个版本都无法仅容纳版本 7 或仅容纳版本 8。

有没有办法在装饰器中执行 if-else 操作?

我可以做到这一点,但它真的很难看,而且如果我必须做出一些更改,我认为维护同一功能的 2 个副本是不可持续的。

from x import x

if x.__version__.split('.')[0] == '7':
    @x.resultcallback()
    def process_pipeline(func, **kwargs):
        with x.get_stream as fin:
            func(fin)
elif x.__version__.split('.')[0] == '8':
    @x.result_callback()
    def process_pipeline(func, **kwargs):
        with x.get_stream as fin:
            func(fin)
Run Code Online (Sandbox Code Playgroud)

有没有办法做类似的事情:

if x.__version__.split('.')[0] == '7':
    @x.resultcallback()
elif x.__version__.split('.')[0] == '8':
    @x.result_callback()
def process_pipeline(func, **kwargs):
    with x.get_stream as fin:
        func(fin)
Run Code Online (Sandbox Code Playgroud)

或者类似的东西:

try:
    @x.resultcallback()
except:
    @x.result_callback()
def process_pipeline(func, **kwargs):
    with x.get_stream as fin:
        func(fin)
Run Code Online (Sandbox Code Playgroud)

che*_*ner 6

您只需将适当的装饰器分配给单个名称即可。

if x.__version__.split('.')[0] == '7':
    result_callback = x.resultcallback
elif x.__version__.split('.')[0] == '8':
    result_callback = x.result_callback


@result_callback
def process_pipeline(func, **kwargs):
    with x.get_stream as fin:
        func(fn)
Run Code Online (Sandbox Code Playgroud)

您也可以使用from ... import ...语句来编写此内容,而不必担心实际的版本号。

try:
    # Old versions
    from x import resultcallback
except ImportError:
    # New versions
    from x import result_callback as resultcallback
Run Code Online (Sandbox Code Playgroud)

  • 这不是猴子修补。我不会更改原始库,只是为“x”公开的属性定义一个新名称。 (2认同)