Python - Decorators

后端 未结 5 453
礼貌的吻别
礼貌的吻别 2020-12-10 12:32

I\'m trying to learn Decorators . I understood the concept of it and now trying to implement it.

Here is the code that I\'ve written The code is se

相关标签:
5条回答
  • 2020-12-10 12:53

    Your decorator should look like this:

    def wrapper(func):
        def inner(x, y): # inner function needs parameters
            if issubclass(type(x), int): # maybe you looked for isinstance?
                return func(x, y) # call the wrapped function
            else: 
                return 'invalid values'
        return inner # return the inner function (don't call it)
    

    Some points to note:

    • issubclass expects a class as first argument (you could replace it with a simple try/except TypeError).
    • the wrapper should return a function, not the result of a called function
    • you should actually call the wrapped function in the inner function
    • your inner function didn't have parameters

    You can find a good explanation of decorators here.

    0 讨论(0)
  • 2020-12-10 12:59

    You may also raise an exception if you would like to terminate the add method properly if type check fails. like this

    def check_int_types(func):
        def type_checker(x, y):
            if issubclass(type(x), int) and issubclass(type(y), int):
                return func(x, y)
            raise Exception("Invalid types: {}, {}".format(x, y))
        return type_checker
    
    @check_int_types
    def add(a, b):
        return a + b
    
    def main():
        x = y = 15.0
        print add(x, y)
    
    if __name__ == '__main__':
        main()
    

    Result:

    Traceback (most recent call last):
      File "deco_test.py", line 17, in <module>
        main()
      File "deco_test.py", line 14, in main
        print add(x, y)
      File "deco_test.py", line 5, in type_checker
        raise Exception("Invalid types: {}, {}".format(x, y))
    Exception: Invalid types: 15.0, 15.0
    
    0 讨论(0)
  • 2020-12-10 13:03

    What about this .

    def wrapper(func):
        def inner():
            if isinstance(func,int):
                    return func(x, y)
            else: return 'invalid values'
    
        return inner()
    
    0 讨论(0)
  • 2020-12-10 13:04

    this might work.

    def wrapper(func):
        def inner(*args,**kwargs):
            if ((args[0] is int) and (args[1] is int)): pass
            else: return 'invalid values'
        return inner
    @wrapper
    def add(x,y):
        return x+y
    print add('a',2)
    
    0 讨论(0)
  • 2020-12-10 13:07

    There are three issues I see with your current code.

    First, you're calling the inner function, rather than returning a reference to it.

    Second, your inner function doesn't take the same arguments as the function you're decorating. In this case, you need to take at least the x argument explicitly (some inner functions can use *args and **kwargs exclusively, but aparently not yours).

    Lastly, you're never calling the wrapped function. While this isn't strictly required (it might be useful to swap out a method with a decorator during development), usually you want to call the function at some point during the inner function's code.

    So, to wrap the whole thing together, I think you want your code to be something like this:

    def wrapper(func):
        def inner(x, y):
            if issubclass(x, int): # issue 2
                return func(x, y) # issue 3
            else:
                return "invalid values" # consider raising an exception here instead!
    
        return inner # issue 1
    
    0 讨论(0)
提交回复
热议问题