zoukankan      html  css  js  c++  java
  • python高阶函数:__init__ , __call__ ,装饰器, hook 的应用和区别

    一  :__init__()__call__()的区别如下: 

    1. __init__()的作用是初始化某个类的一个实例。 
    2. __call__()的作用是使实例能够像函数一样被调用,同时不影响实例本身的生命周期(__call__()不影响一个实例的构造和析构)。但是__call__()可以用来改变实例的内部成员的值。

    class Mark(object):

    def __init__(self, str):
    print("__init__", str)

    def __call__(self, func):
    print("__call__", func)


    mark=Mark("str") # 声明一个实例,调用__init__传参str
    mark("func") # 引用该类实例,调用__call__传参func

    -----------------------------
    输出结果为:
    __init__str
    __call__func



    二: 装饰器和语法糖

    装饰器版本:
    def func():
      print("被装饰的函数")
    def add_way(func):  # 1
    def wrapper(): # 3
    print('这是新功能') # 6
    func() # 7

    return wrapper # 4

    func = add_way(func) # 2
    func()

    语法糖版本:
    def add_way(func):
    def wrapper():
    print('这是新功能')
    func()

    return wrapper

    @add_way
    def func():
    print("语法糖版本:被装饰函数")

    func()

    Python提供了一个 语法糖 "@" 来帮我们完成func = add_way(func)这件事情! 所以“@”和__call__组合使用时,已经完成了__call__的逻辑并返回该函数,而不是在调用函数时
    class Mark:

    def __init__(self, module: str = ''):
    print("__init__:", module)

    def __call__(self, func):
    print("__call__:", func.__name__)
    return func


    class Api:
    mark = Mark


    api = Api()


    class Demo:

    @staticmethod
    @api.mark(module='demo1')
    def demo1():
    print("demo1()被调用")

    @staticmethod
    @api.mark(module='demo2')
    def demo2():
    print("demo2()被调用")


    d = Demo()
    d.demo1()
    d.demo2()


    -------------------
    结果:

    __init__: demo1
    __call__: demo1
    __init__: demo2
    __call__: demo2
    demo1()被调用
    demo2()被调用

    -------------------

     

    带参数的装饰器

    # 带参数的装饰器

    def post(path=''):
    def decorator(func):
    def wrapper(*args, **kwargs):
    print('path:', path)
    func(*args, **kwargs)

    return wrapper

    return decorator


    # () 就是调用了,会decorator返回实例,会初始化,这个decorator实例可以调用,生成wrapper实例
    @post('/login')
    def test_login(name, pwd):
    print('name:', name)
    print('pwd:', pwd)
    print(test_login.__name__) # 最后是个wrapper实例


    def test_login2(name, pwd):
    print('name:', name)
    print('pwd:', pwd)
    print(test_login2.__name__)


    test_login('wjz', '111')
    test_login2('wjz', '111')

    # 看到这个代码是不是又有些疑问,内层的decorator函数的参数func是怎么传进去的?和上面一般的装饰器不大一样啊。
    # 其实道理是一样的,将其@语法去除,恢复函数调用的形式一看就明白了:
    # 传入装饰器的参数,并接收返回的decorator函数
    # decorator = post("/login")
    # 传入test_login函数
    # wrapper = decorator(test_login)
    # 调用装饰器函数
    # wrapper("'wjz', '111'")

    三 : hook函数

     

  • 相关阅读:
    BZOJ3575 [Hnoi2014]道路堵塞
    BZOJ4456/UOJ184 [Zjoi2016]旅行者
    BZOJ4455/UOJ185 [Zjoi2016]小星星
    BZOJ1036 [ZJOI2008]树的统计Count
    BZOJ2594 [Wc2006]水管局长数据加强版
    BZOJ3669/UOJ3 魔法森林(LCT)
    BZOJ1012:[JSOI2008]最大数
    洛谷【P1175】表达式的转换
    HDU4699:Editor
    BZOJ3039:玉蟾宫
  • 原文地址:https://www.cnblogs.com/sylarwang/p/13502770.html
Copyright © 2011-2022 走看看