xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

Python3 & Decorators with arguments & @Decorators with arguments bug

Python3 & Decorators with arguments & @Decorators with arguments bug

@Decorators with arguments bug

# 🚀 add support args
def decor(func, args):
  def wrap(args):
    print("======before calling function======")
    func(args)
    print("======after called function======")
  return wrap

# ✅
def greeting(name):
  print("Hello world!", name)

decorated = decor(greeting, '')
decorated('xgqfrms')

# ❌ bug ❓
@decor('')
def greeting(name):
  print('@修饰符号')
  print('Hello world!', name)

greeting('xgqfrms')

__init__ & __call__


# Decorators with Arguments

"""

https://python-3-patterns-idioms-test.readthedocs.io/en/latest/PythonDecorators.html#decorators-with-arguments
https://www.geeksforgeeks.org/decorators-with-parameters-in-python/
https://stackoverflow.com/questions/5929107/decorators-with-parameters

"""

# PythonDecorators/decorator_with_arguments.py
class decorator_with_arguments(object):
  def __init__(self, arg1, arg2, arg3):
    # TypeError: __init__() takes 4 positional arguments but 5 were given
    """
      If there are decorator arguments, the function
      to be decorated is not passed to the constructor!
    """
    print("1. Inside __init__()")
    self.arg1 = arg1
    self.arg2 = arg2
    self.arg3 = arg3

  def __call__(self, f):
    """
      If there are decorator arguments, __call__() is only called
      once, as part of the decoration process! You can only give
      it a single argument, which is the function object.
    """
    print("2. Inside __call__()")
    def wrapped_f(*args):
      print("\n5. Inside wrapped_f()")
      print("6. Decorator arguments:", self.arg1, self.arg2, self.arg3)
      f(*args)
      print("8. After f(*args)")
    # return OK ✅ ??? __call__ 闭包函数 ???
    return wrapped_f
      # return bug ❌
      # return wrapped_f

@decorator_with_arguments("a1", "a2", "a3")
def sayHello(a1, a2, a3, a4):
  print('7. sayHello arguments: \n', a1, a2, a3, a4)

# @decorator_with_arguments("a1", "a2", "a3")
# def sayHello(a1, a2, a3, a4):
#   print('sayHello arguments:', a1, a2, a3, a4)


print("3. After decoration")
print("4. Preparing to call sayHello()")

sayHello("say", "hello", "argument", "list")
# TypeError: 'NoneType' object is not callable

print("9. after first sayHello() call\n")

sayHello("a", "different", "set of", "arguments")

print("9. after second sayHello() call")


"""

# test
$ python3 decorators-at-with-arguments.py

"""

"""
1. Inside __init__()
2. Inside __call__()
3. After decoration
4. Preparing to call sayHello()

5. Inside wrapped_f()
6. Decorator arguments: a1 a2 a3
7. sayHello arguments:
 say hello argument list
8. After f(*args)
9. after first sayHello() call


5. Inside wrapped_f()
6. Decorator arguments: a1 a2 a3
7. sayHello arguments:
 a different set of arguments
8. After f(*args)
9. after second sayHello() call

"""


refs

https://www.cnblogs.com/xgqfrms/p/13494857.html

https://www.sololearn.com/Discuss/New



©xgqfrms 2012-2020

www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!


posted @ 2020-08-13 15:10  xgqfrms  阅读(203)  评论(5编辑  收藏  举报