Search code examples
pythondecoratortry-except

Is there a way to do if-else / try-except for decorator functions?


There's this library X that has two versions, 7 and 8.

In version 7, the callback for the decorator is called resultcallback() and

in version 8, the callback is called result_callback():

Currently I've a code that does something like this with version 7 of library X:

from x import x  # Some sort of decorator library.

@x.resultcallback()
def process_pipeline(func, **kwargs):
    with x.get_stream as fin:
        func(fin)

I've users that wants to only depend on either of the versions and both are not able to accommodate either only version 7 or only version 8.

Is there a way to do an if-else at the decorator?

I could do this but it's really ugly and I don't think maintaining 2 copies of the same function is sustainable if I've some changes that I've to make.

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)

Is there some way to do something like:

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)

Or something like:

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

Solution

  • You can simply assign the appropriate decorator to a single name.

    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)
    

    You could also write this using an from ... import ... statement, without worrying about the actual version numbers.

    try:
        # Old versions
        from x import resultcallback
    except ImportError:
        # New versions
        from x import result_callback as resultcallback