Passing a parameter to the decorator in python

前端 未结 2 1635
小蘑菇
小蘑菇 2021-01-12 13:40

Why is this decorator with a parameter not working?

def decAny( f0 ):
    def wrapper( s0 ):
        return \"<%s> %s \" % ( any, f0(), any          


        
相关标签:
2条回答
  • 2021-01-12 14:26

    Decorators are functions that return functions. When "passing a parameter to the decorator" what you are actually doing is calling a function that returns a decorator. So decAny() should be a function that returns a function that returns a function.

    It would look something like this:

    import functools
    
    def decAny(tag):
        def dec(f0):
            @functools.wraps(f0)
            def wrapper(*args, **kwargs):
                return "<%s> %s </%s>" % (tag, f0(*args, **kwargs), tag)
            return wrapper
        return dec
    
    @decAny( 'xxx' )
    def test2():
        return 'test1XML'
    

    Example:

    >>> print(test2())
    <xxx> test1XML </xxx>
    

    Note that in addition to fixing the specific problem you were hitting I also improved your code a bit by adding *args and **kwargs as arguments to the wrapped function and passing them on to the f0 call inside of the decorator. This makes it so you can decorate a function that accepts any number of positional or named arguments and it will still work correctly.

    You can read up about functools.wraps() here:
    http://docs.python.org/2/library/functools.html#functools.wraps

    0 讨论(0)
  • 2021-01-12 14:32

    There is a good sample from "Mark Lutz - Learning Python" book:

    def timer(label=''):
        def decorator(func):
            def onCall(*args):   # Multilevel state retention:
                ...              # args passed to function
                func(*args)      # func retained in enclosing scope
                print(label, ... # label retained in enclosing scope
            return onCall
        return decorator         # Returns the actual decorator
    
    @timer('==>')                # Like listcomp = timer('==>')(listcomp)
    def listcomp(N): ...         # listcomp is rebound to new onCall
    
    listcomp(...)                # Really calls onCall
    
    0 讨论(0)
提交回复
热议问题