zoukankan      html  css  js  c++  java
  • 修饰器学习

    第一步:(简单的函数调用)

    def myfunc()

        print('myfunc() called.")

    myfunc()

    第二步:(修饰器本质的调用原理,修饰器内调用被修饰的函数)

    def deco(func):
        print('before myfunc() called.')
        func()
        print('after myfunc() called')

    def myfunc():
        print('myfunc() called')

    myfunc=deco(myfunc)#最重要的一步,修饰器就是一个函数,一个容器,用来放进其他函数修饰,改变,在函数前后添加内容的

    第三步:最简单的修饰器(相当于“myfunc = deco(myfunc)”)

    def deco(func):
        print('before myfunc() called.')
        func()
        print('after myfunc() called.')
        return func

    @deco
    def myfunc():
        print('myfunc() called')

    第四步:内嵌包装函数(保护函数)

    def deco(func):
        def _deco():
            print('before myfunc() called.')
            func()
            print('after myfunc() called.')
        return _deco

    @deco
    def myfunc():
        print('myfunc() called')

    myfunc()

    第五步:被修饰的函数有参数

    修饰器第二层函数需要有被修饰函数的参数,并且第二层返回被修饰函数运行后的值,被修饰函数也要返回值

    def deco(func):
        def _deco(a,b):
            print('before myfunc() called.')
            ret=func(a,b)
            print('after myfunc() called. result:%s' % ret)
            return ret
        return _deco

    @deco
    def myfunc(a,b):
        print('myfunc(%s,%s) called.' % (a,b))
        return a+b

    myfunc(1,2)

    第六步:被修饰的函数不确定数量(使用*args,**kwargs)

    def deco(func):
        def _deco(*args,**kwargs):
            print('before %s called.' % func.__name__)
            ret=func(*args,**kwargs)
            print('after %s called. result:%s' % (func.__name__,ret))
            return ret
        return _deco

    @deco
    def myfunc(a,b):
        print('myfunc(%s,%s) called.' % (a,b))
        return a+b

    @deco
    def myfunc2(a,b,c):
        print('myfunc2(%s,%s,%s) called.' % (a,b,c))
        return a+b+c

    myfunc(1,2)
    myfunc2(1,2,3)

    总的来说,就是把修饰器第二层的固定参数,改为(*args,**kwargs),被修饰函数就可以接受不确定数量的参数了

    第七步:带参数的修饰器,使修饰器更灵活,可控,参数可控制这个函数的作用,和特征

    def deco(args):
        def _deco(func):
            def __deco():
                print('before %s called [%s].' % (func.__name__,args))
                func()
                print('after %s called [%s]' % (func.__name__,args))
            return __deco
        return _deco


    @deco('module1')
    def myfunc():
        print('myfunc() called')

    @deco('module2')
    def myfunc2():
        print('myfunc2() called')

    myfunc()
    myfunc2()

    解析:如果修饰器带有参数,那么修饰器需要三层,第一层,args是修饰器的参数,第二层参数是传进被修饰函数,第三层没有参数

     第八步:装饰器的参数是类

    class locker:
        def __init__(self):
            print("locker.__init__() should be not called.")
             
        @staticmethod
        def acquire():
            print("locker.acquire() called.(这是静态方法)")
             
        @staticmethod
        def release():
            print("  locker.release() called.(不需要对象实例)")
     
    def deco(cls):
        '''cls 必须实现acquire和release静态方法'''
        def _deco(func):
            def __deco():
                print("before %s called [%s]." % (func.__name__, cls))
                cls.acquire()
                try:
                    return func()
                finally:
                    cls.release()
            return __deco
        return _deco
     
    @deco(locker)
    def myfunc():
        print(" myfunc() called.")
     
    myfunc()

    解析:和第七步差不多一样装饰器,第一层参数是修饰器参数,第二层是函数,第三层没有参数.只是传进了类,可以相当于实例化一个类,可以用类里面的东西

    第九步:装饰器带类参数,并分拆公共类到其他py文件中,同时演示了对一个函数应用多个装饰器

    这步没多少难度,暂时跳过

  • 相关阅读:
    Android Studio快速定位当前文件所在的位置
    LeetCode:Search Insert Position
    apk当安装程序将文件复制到手机自带的指定文件夹
    《UNIX级别编程环境》注意读出信号(2)
    iOS:删除小程序
    百度CSND博客在搜索栏中显示图片
    HDU4893:Wow! Such Sequence!(段树lazy)
    Google I/O 2014? No,Android I/O 2014
    Android Push Notifications using Google Cloud Messaging (GCM), PHP and MySQL
    自己动手写CPU 笔记
  • 原文地址:https://www.cnblogs.com/thouger/p/5931635.html
Copyright © 2011-2022 走看看