zoukankan      html  css  js  c++  java
  • 高函、闭包、装饰、类

    函数被调用时:
    1、函数后有(),是v——函数执行,要调回头或跳到下方某处,进入此函数块内执行;
    2、只有函数名而无(),是n——函数体,按照正常顺序往下执行,不用跳来跳去。
     
    理解装饰器,可把头&尾的def finalFunc(*args, **kwargs):、return finalFunc,视为不存在。
    *******************分割线*******************
    函数内若改了全局变量v,并使之同步到函数外,则要在此函数内的首行加句global v。
     
    函数的形参若设了list、set、dict等可变类型的默认值,则似全局变量 :
    import random
     
    def foo(a={2}):
        a.add(random.randint(1,50))
        print(a)
     
    for x in range(9):
        foo()
    *******************分割线*******************
    f用于{}的格式化,{}内是变量或函数的某个形参;%s等%家族的格式化则不适用。
    f'{xxx}'内的+-/*等Python内置对象,意义没变,只想表示普通str则写在{}外,如{}和{}之间。
     
    def func(name):
        greet='good morning'
        print(f'{greet},{name}')
     
    func('小明')
    ****************************************分割线****************************************
    高阶函数:参数为函数;闭包:返回值为函数;装饰器:返回值为函数的高阶函数
     
    高阶函数:
     
    from functools import reduce
     
    # map的首参函数逐一作用于二参序列的各元素,返回同len的序列;
    # 而reduce的首参函数必须有俩参,迭代处理二参序列的相邻元素,返回1个值
    def accumulate(start, end, handle, sign):
        t = map(handle, range(start, end + 1))
        return reduce(lambda x, y: eval(f'{x}{sign}{y}'), t)
     
    def add(start, end, handle):
        return accumulate(start, end, handle, '+')
     
    def product(start, end, handle):
        return accumulate(start, end, handle, '*')
     
    def handle(n):
        return n ** 2
     
    print(add(1,4, handle))
    ****************************************分割线****************************************
    闭包:
     
    def count():
        #x=i:x是匿名函数的形参,i是实参;不写=i,则报错lambda()缺少参数(实参)
        return [lambda x=i:x*x for i in range(1,4)]    #生成3个传来了实参的函数体
     
    x,y,z=count()
    print(x(),y(),z(),sep=';')
    *******************分割线*******************
    def func():
        x,y=1,2
        return lambda m=x,n=y:m+n    #m=x,n=y:x和y是默认实参
     
    print(func()()) #输出3,即1+2
    print(func()(3,7))  #输出10,即3+7
    ****************************************分割线****************************************
    #函数实现的双层装饰器
     
    from functools import wraps #保持被装饰函数原有的属性值和方法行为
     
    def outer(initialFunc): # 给原函数套俩彩盒,由外至内逐层开盒
        @wraps(initialFunc) #用wraps保护传来的被装饰函数的属性和方法
        def finalFunc(*args, **kwargs):
            print('begin to run outer decorator')
            initialResponse=initialFunc(*args, **kwargs)    #等同inner('自带参数')(func)(x,y=6)
            print('end outer decorator')
            return initialResponse
        return finalFunc
     
    def inner(selfArgument):  # 高阶装饰器:自身也带参数
        def realDecorator(initialFunc): #高阶装饰器,要多一层方法嵌套
            @wraps(initialFunc)
            def finalFunc(*args, **kwargs):  # 装饰器的俩轮子
                print(selfArgument, '——begion to run higher decorator')
                #参数*和**是装饰器的俩轮子,()是装饰器的一对翅膀
                initialResponse=initialFunc(*args, **kwargs) + 9   #暂不return,让后面的print也能执行
                print('end higher decorator')
                return initialResponse  #下面两行的return不能加(),是普通函数体,不是翅膀
            return finalFunc
        return realDecorator
     
    @outer  # func(x,y=6)=outer(inner('自带参数')(func))(x,y=6)
    @inner('自带参数')  # func(x,y=6)=inner('自带参数')(func)(x,y=6)
    def initialFunc(x, y=6):
        print('begin to run initial function')
        return x + y  # 此处的return,对应上文inner装饰器内的initialFunc(*args,**kwargs)
     
    print(initialFunc(2, 3))
    ******************分割线*******************
    #类实现的自带参数的高阶装饰器
     
    import time
    from functools import wraps
     
    class Timeit:
        def __init__(self, selfArgument):
            self.selfArgument = selfArgument
     
        def __call__(self, initialFunc):
            @wraps(initialFunc)
            def finalFunc(*args, **kwargs):
                start = time.time()
                initialResponse=initialFunc(*args, **kwargs) * 3
                end = time.time()
                print('%s运行了%d秒' % (self.selfArgument, int(end - start)))
                return initialResponse
            return finalFunc
     
    @Timeit('自带参数的装饰器')
    def initialFunc(s):
        time.sleep(1.5)
        print(s)
        return s
     
    result=initialFunc('hello,world!')
    print(result)
    ****************************************分割线****************************************
    #类的继承、多态
     
    class Person:
        def __init__(self, name, job=None, pay=0):
            self.name = name
            self.job = job
            self.pay = pay
     
        def __str__(self):  # print函数
            return 'personInfo:%s,%s' %(self.name, self.pay)
     
        def salary(self, percent):
            self.pay = int(self.pay * (1 + percent))
     
        def lastName(self):
            return self.name.split()[-1]
     
    class Manager(Person):
        def salary(self, percent, bonus=0.1):
            Person.salary(self, percent + bonus)    #继承
     
    David = Person('David Alex')
    Jack = Person('Jack Ma', 'Speaker', 5000)
    Bill = Manager('Bill Gates', 'IT', 10000)
     
    Jack.salary(0.2)
    Bill.salary(0.3, 0.2)
    [print(obj.lastName(), '…………', obj) for obj in (David, Jack, Bill)]
     
    for obj in (David, Jack, Bill):
        obj.salary(0.1)    #多态:对象不同,则调用的salary版本不同
        print(obj)
    ****************************************分割线****************************************
    类继承中的super:
     
    1、super多重继承的构造及实例函数,同普通多继承:广度优先,懒惰模式,即在匹配到第一个长辈类后就终止。
     
    2、但是若首个长辈类也有super,就是贪婪模式了:公共爷类(如class E继承了B、C、D,而B、C、D又继承了A),仅执行一次;各父类的super前的代码是广度序,之后的代码是广度序。
     
    class A:
        def __init__(self):
            print("Enter A")
            print("Leave A")
     
    class B(A):
        def __init__(self):
            print("Enter B")
            super(B, self).__init__()
            print("Leave B")
     
    class C(A):
        def __init__(self):
            print("Enter C")
            super(C, self).__init__()
            print("Leave C")
     
    class D(A):
        def __init__(self):
            print("Enter D")
            super(D, self).__init__()   #此句取注或注释后,各运行一次,观察两次结果的区别
            print("Leave D")
     
    class E(B, C, D):
        def __init__(self):
            print("Enter E")
            super(E, self).__init__()
            print("Leave E")
     
    E()
    ****************************************分割线****************************************
    type函数生成class:
     
    def fn(self, name='world'):
        print('Hello, %s!' % name)
        print(self.move)
     
    class Animal:
        move='run'
     
    #type的首参是类名,二参()内是各父类,三参{}内是各方法或类属性
    Dog = type('Dog', (Animal,), {'hi':fn,'attr':'xxx'})
    xh=Dog()
    xh.hi()
    print(xh.attr)
    ****************************************分割线****************************************
    自定义异常:
     
    class MyError(Exception):
        def __init__(self, value):
            self.value = value
        def __repr__(self):
            return self.value
     
    try:
        raise MyError(2**3)
    except MyError as e:
        print('My exception occurred, value:', e)
  • 相关阅读:
    浙大数据结构课后习题 练习二 7-2 Reversing Linked List (25 分)
    浙大数据结构课后习题 练习二 7-2 一元多项式的乘法与加法运算 (20 分)
    浙大数据结构课后习题 练习一 7-1 Maximum Subsequence Sum (25 分)
    浙大数据结构课后习题 练习一 7-1 最大子列和问题 (20 分)
    PAT Basic 1019 数字黑洞 (20 分)
    PAT Basic 1017 A除以B (20 分)
    PAT Basic 1013 数素数 (20 分)
    PAT Basic 1007 素数对猜想 (20 分)
    PAT Basic 1003 我要通过! (20 分)
    自动化运维——HelloWorld(一)
  • 原文地址:https://www.cnblogs.com/scrooge/p/7686545.html
Copyright © 2011-2022 走看看