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)
  • 相关阅读:
    C# 设计原则-单一职责原则
    C# Linq的简单运用
    .Net Core中的管道机制
    .Net Core和.Net Framework的区别
    C# 9.0 新特性简析
    .Net core的依赖注入
    .Net IOC容器unity的使用
    网站被黑客攻击百度出现警示
    七牛云免费对象存储(解决图片加载缓慢问题)
    今天第一篇博客 说点随意的内容
  • 原文地址:https://www.cnblogs.com/scrooge/p/7686545.html
Copyright © 2011-2022 走看看