Python精进之路

本专题的内容结构:python

unit1:精进的Python语法:编程

    (1),上下文管理器:多线程

        上下文Conteext:程序执行中的某个状态app

            >程序执行所需的一些内外部参数,构成了程序运行时状态dom

            >上下文是用来表达程序运行状态的概念,对应内存状态异步

            >上下文是程序中断保留或恢复运行的重要状态信息async

 

        上下文管理器:一个能够在程序中加载独立上下文的对象异步编程

            >万物皆对象:上下文管理器也是一个对象,管理着一个独立上下文区域函数

                简单说就是在程序中能够中止程序,运行程序的对象学习

            >上下文管理器使用with 显示建立

            >进入和退出分别对应 __enter__() 和__exit__() 方法

            

 

 

            简单实例:用它来管理文件的操做:

                with open("python123.txt",'r') as f:

                    for line in f:

                        print(line)

               

                >with结束后,文件被自动关闭

                也能够打开多个文件:

                    with open("a.txt",'r') as fi,open("b.txt",'w') as fo:

                        for line in fi:

                            fo.write(line)

                >with 结束后,两个文件都会被关闭

 

                由于进入(__enter__())时操做的是打开文件,因此离开时,会关闭这个操做

            自定义上下文管理器:

                class DemoClass:

                    def __init__(self,name):

                        self.name= name

 

                    def __enter__(self):

                        print("进入上下文管理器")

                        return self

 

                    def __exit__(self, exc_type, exc_val, exc_tb):

                        print("退出上下文管理器")

 

                    def run(self):

                        print("DemoClass 的某个实例对象在运行")

 

                with DemoClass("python123") as d:

                    d.run()   

                输出:

                    进入上下文管理器

                    DemoClass 的某个实例对象在运行

                    退出上下文管理器

 

                注:如何使用上下文管理器:

                    >1,with要配合特定对象使用

                    >2,Python支持:

                        file,

                        decimal.Context,

                        thread.LockType,

                        threading.Lock,

                        threading.RLock,

                        threading.Condition,

                        threading.Semaphore,

                        threading.BoundedSempahore

                    >用户也可自定义对象

                自定义的open类:

                    class MyOpenClass:

                        def __init__(self,name,mode):

                            self.name= name

                            self.mode= mode

 

                        def __enter__(self):

                            print("进入上下文管理器")

                            if self.mode == 'r':

                                self.f = open(self.name,self.mode)

                            else:

                                self.f= open(self.name,self.mode)

                            return self #重点,要将self, 它返回的就是as 后面的那个

 

                        def __exit__(self, exc_type, exc_val, exc_tb):

                            self.f.close()

                            print("退出上下文管理器")

                        def read(self):

                            return self.f.read()

 

                        def write(self,s):

                            self.f.write(s)

 

                    with MyOpenClass("d:/test.txt",'r') as f1,MyOpenClass("d:/test02.txt",'w') as f2:

                        txt = f1.read() #从f1中读

                        print(txt)

                        f2.write(txt)  # 写到f2中去

 

    (2),迭代器类型:

        迭代器类型 Iterator Types :实现容器中元素的迭代:

            >Container:包含一组元素的数据类型,如 所有组合数据类型

            >迭代器:容器之上的一种迭代,迭代方式以对象形式表达

            >迭代器定义了逐一获取容器中元素的方法

 

        迭代器是一个对象,常与for ..in 配合使用,须要重载两个方法:

            >__iter__() 返回迭代器对象自身,配合for ..in 使用时须要

            >__next__() 返回容器的下一个元素,若是遍历结束,产生StopIteration异常

        简言之,迭代器就是一个对象有__iter__() 和__next__() 方法,还有一个异常,

            只要是有这两个方法,还有一个异常,它就是迭代器,它就能够配合for in 使用

       

        例子:

            class DemoIterator:

                def __init__(self,container):

                    self.container = container

                    self.arg = len(self.container)

 

                def __iter__(self):

                    return self  #必须返回自身,for in 的要求

 

                def __next__(self):

                    self.arg -=1

                    if self.arg >=0:

                        return self.container[self.arg]

                    else:

                        raise StopIteration

            di = DemoIterator([1,2,3,4,5,6,7,8,9])

            for i in di:

                print(i,end=',')

           

            输出:

                9,8,7,6,5,4,3,2,1,

        迭代器类型 Iterator Types:实现容器中元素的迭代

            >迭代器很是经常使用,尤为是涉及到管理一组数据的应用场景

            >自定义类 + for..in 管理一组数据,做为数据管理的核心自定义数据类型

            >迭代器返回下一个元素的方式为优化程序内存使用提供了重要支持

 

    (3),生成器类型:

        生成器 Generator:快速实现迭代器类型的方式:

            >生成器是迭代器的另外一个角度诠释,生成器都是迭代器

            >生成器以逐一产生数据为角度,重点在于迭代逻辑的方便实现

            >生成器只须要yield保留字便可定义并表达,不用重载对象方法

 

        生成器函数 Generator Function :实现迭代逻辑的函数:

            >生成器函数是生成器的核心,用来实现迭代逻辑

            >任何包含yield语句的函数,都是生成器函数

            >对于函数来讲,yield和return 功能接近,但不彻底相同

 

            例子:

                正常的函数:

                def getVal():

                    import random

                    ls = list(range(10))

                    print(ls,end=',')

                    return ls[random.randint(0,9)]

 

                for i in range(10):

                    print(getVal())

                输出:

                    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],5

                    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],6

                    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],7

                    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],0

                    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],2

                    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],4

                    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],7

                    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],3

                    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],6

                    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],5

                    注:普通函数:

                        1,每次调用完整执行后退出

                        2,若是函数表达了容器概念也如此

                        形成了计算资源浪费!它每次都从新生成一个列表

            生成器解决了这个问题:

                例子:

                    def getVal(max):

                        import random

                        ls = list(range(10))

                        print(ls,end=',')

                        for _ in range(max):

                            yield ls[random.randint(0,9)] #每调一次getVal() 就会执行一次,而后停在yield处

 

                    for i in getVal(10):

                        print(i)

                    输出:

                        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],1

                        5

                        7

                        4

                        7

                        5

                        9

                        3

                        7

                        9

            生成器函数的设计原则:

                >若想不断生成数据, 生成器函数须要存在迭代/循环过程

                >每次迭代/循环产生的结果以yield方式表达

                >生成器函数要与for ..in 配合使用,注意:生成器是一种特殊的迭代器

 

            生成器是特殊的迭代器:也有__next__(),__iter__() ,和stopIteration异常

                def getVal(max):

                    import random

                    ls = list(range(10))

                    print(ls,end=',')

                    print()

                    for _ in range(max):

                        yield ls[random.randint(0,9)]

 

                a = getVal(10)

 

                print(a.__next__())

                print(a.__next__())

                [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],

                8

                2

    (4),装饰器与语法糖:

        装饰器 Decorator:以函数为参数实现其额外功能

            >需求:对于一个已有函数,如何更新其功能?(同名使用)

            >解决方式1: 从新编写喊,把功能补充进去

            >解决方式2:不改变原来函数,增补一个装饰器给它

            缘由是:有的函数是第三方库中的,有的是长期使用的函数不能随意修改它,

                因此最好的方法是额外增长功能,

 

            以前讲过装饰器:

                classmethod() 和staticmethod() 的内置函数(经过装饰器)

                    它们参数是函数名

                    >@classmethod 和 @staticmethod

                例子:

                    <图>

                    两者是等价的

            语法糖 Syntactic Sugar :方便使用但无实质功能的语法

                >语法糖:一种功能的简化使用方式,非功能性改变

                >Python中采用@做为语法糖,辅助装饰器使用

                >任何语法糖表达的装饰器都对应一个函数

               

                并且语法糖能够迭代使用:

                    @f2

                    def func():

                        pass

                    它等价于

                        func = f2(func)

 

                    这就是语法糖配合装饰器使用来简化 python代码的过程

 

            简单说,语法糖不重要,重要的是装饰器函数:

            装饰器设计原理 :

                >语法糖不重要,重要的是装饰器函数,该函数以函数为参数

                >因为可能存在装饰器迭代,每一个装饰器函数须要返回一个函数引用

                >装饰器内部,进行功能扩展

 

                原始函数:

                    def func3(a):

                        print("这是变量{}".format(a))

 

                    func3("python123")

                如今要对它扩展功能:

                    def func1(func):

                        def wrapper(a):

                            print("我是扩展的")

                            func(a)

                            print("我也是扩展的")

                        return wrapper  #必须返回一个函数对象引用,不然没法利用语法糖

 

                    @func1  #等价于 func3 = func1(func3)  因此,func1必定要返回函数引用

                    def func3(a):  #这时的@func1 和def func3(a) 合起来是个新的函数

                        print("这是变量{}".format(a))

 

                    func3("python123")

 

                总结:

                    def func1(func):

                        def wrapper(a):

                            func(a)

                            print("扩展的")

                        return wrapper

 

                    @func1

                    def func3(a):

                        print(a)

 

                    func3("heello ") #其实它执行的是wrapper("hello ")

               

 

                装饰器的使用场景:

                    >对原函数功能的补充:测量时间,增长打印

                    >对原函数功能的调整:利用原函数运行结果,再次运算产生新的结果

                    >对原函数功能的重写:只是借助原来的名字,谨慎修改旧函数

 

                综合例子:

                "mx 为matrix 矩阵"

                def decorator(func):

                    def wrapper(mx1,mx2,mx1_row,mx1_col,mx2_col):

                        t1= time.perf_counter()

                        func(mx1,mx2,mx1_row,mx1_col,mx2_col)

                        print("{:.5f}".format(time.perf_counter()-t1))

                    return wrapper

 

 

                @decorator

                def mxmul(mx1,mx2,mx1_row,mx1_col,mx2_col):

                    rst = [[0 for y in range(mx2_col)] for x in range(mx1_row)]

                    for i in range(mx1_row):  #mx1行

                        for j in range(mx1_col): # mx1列 mx2行

                            for k in range(mx2_col): #mx2列

                                rst[i][k] += mx1[i][j] *mx2[j][k]

                    return rst

 

                def mxsum(mx,mx_row,mx_col):

                    s = 0

                    for i in range(mx_row):

                        for j  in range(mx_col):

                            s += mx[i][j]

                    return s

 

                if __name__ =="__main__":

                    import time

                    mx1 = [[1,2,3],[7,8,2],[4,2,5]]

                    mx2 = [[1,2],[9,8],[11,7]]

                    mx1_row = len(mx1)

                    mx1_col = len(mx1[0])

                    mx2_row = len(mx2)

                    mx2_col = len(mx2[0])

 

                    rst = mxmul(mx1,mx2,mx1_row,mx1_col,mx2_col)

                    sum1 = mxsum(mx1,mx1_row,mx1_col)

                    sum2 = mxsum(mx2,mx2_row,mx2_col)

                    print(rst)

                    print(sum1,sum2)

                    输出:

                        0.00002

                        None

                        34 38

 

                    咱们的目的是给mxmul计时,可是输出结果里却没了计算结果:

                        这时由于咱们的wrapper里没有返回计算的结果,(其实被装饰的函数已经变成了wrapper),

                            因此要把须要返回的结果返回

                        修改以下:

                            "mx 为matrix 矩阵"

                            def decorator(func):

                                def wrapper(mx1,mx2,mx1_row,mx1_col,mx2_col):

                                    t1= time.perf_counter()

                                    ret = func(mx1,mx2,mx1_row,mx1_col,mx2_col)

                                    print("{:.5f}".format(time.perf_counter()-t1))

                                    return ret

                                return wrapper

 

 

                            @decorator

                            def mxmul(mx1,mx2,mx1_row,mx1_col,mx2_col):

                                rst = [[0 for y in range(mx2_col)] for x in range(mx1_row)]

                                for i in range(mx1_row):  #mx1行

                                    for j in range(mx1_col): # mx1列 mx2行

                                        for k in range(mx2_col): #mx2列

                                            rst[i][k] += mx1[i][j] *mx2[j][k]

                                return rst

 

                            def mxsum(mx,mx_row,mx_col):

                                s = 0

                                for i in range(mx_row):

                                    for j  in range(mx_col):

                                        s += mx[i][j]

                                return s

 

                            if __name__ =="__main__":

                                import time

                                mx1 = [[1,2,3],[7,8,2],[4,2,5]]

                                mx2 = [[1,2],[9,8],[11,7]]

                                mx1_row = len(mx1)

                                mx1_col = len(mx1[0])

                                mx2_row = len(mx2)

                                mx2_col = len(mx2[0])

 

                                rst = mxmul(mx1,mx2,mx1_row,mx1_col,mx2_col)

                                sum1 = mxsum(mx1,mx1_row,mx1_col)

                                sum2 = mxsum(mx2,mx2_row,mx2_col)

                                print(rst)

                                print(sum1,sum2)

                            输出结果:

                                0.00002

                                [[52, 39], [101, 92], [77, 59]]

                                34 38

 

 

 

 

           

 

 

    (5),异步协程函数:

        协程Coroutine :在程序层面的多段代码异步执行:

            >Python3.5 新增内置功能:async ,和await保留字

            >async: 用于定义异步执行的协程代码段

            >await:异步代码段之间的手工同步方式

       

        async:

            通常能够对函数,上下文管理器和迭代器使用协程:

                async def foo():  协程函数

                    pass  

                async with lock:  协程上下文管理器

                    pass 

                async for data in pipeline: 协程迭代器

                    pass

        await:

            async def foo(db):

                data = await db.fetch("SELECT ...")

                pass

                获取异步协程的结果,结果为awaitalbe对象

 

            await它是在异步的函数中,等待其余函数返回结果的保留字,

 

        什么是awaitalbe对象,

        咱们一块儿学习异步协程:

            >阅读:,https://www.python.org/dev/peps/pep-0492/

            >理解:理解协程产生的缘由,设计方法及应用理念

            >时间:尝试定义一个协程函数并作初步分析

       

        异步协程主要应用于异步编程,多线程的场景下,

 

unit2:精进的Python语言:

    (1),所有保留字 :

        and or not :逻辑运算保留字

        as :对象引用保留字,至关于绑定别名

            import  as  别名(对象引用)

            try 

                except  as 对象引用

            with ... as  对象应用

        assert:

            断言语句保留字,经过异常进行程序辅助调试,

                assert 判断条件

                若是条件为False ,产生AssertionError 异常

                例如:

                    a = 10

 

                    try:

                        assert a<5

                    except:

                        print("a太大了")

        in :成员关系操做保留字:

            • 成员关系提取:for .. in …

            • 成员关系判断:.. in ..

        is : 对象判断保留字 只用来判断内存是不是同一块

            对象一致性判断,即比较id()函数结果

            之内存对象为判断依据:x is y

        lambda :

            • 定义匿名函数,产生函数对象

            • lambda 参数列表: 表达式  

        yield:

            • 定义一个同步或异步(协程)生成器

            • yield 表达式

        del

            • 解除引用与对象的绑定关系,“删除”引用

            • del 引用

        True /False:

            • True:表示真

            • False:表示假,含 0、0.0、[]、{} 、""等

        None: 空无保留字

            • 表示空无,与False不一样

            • Python最基础的一个对象

 

        等等...

    (2),所有特殊符号

        特殊符号:表达Python语法的三种逻辑

        • 操做符:表达操做运算

        • 分界符:表达式之间的分界

        • 特殊含义:具备特殊含义的符号

        操做符

            + - * ** / // % @

            << >> & | ^ ~

            < > <= >= == !=

            • @ 矩阵乘法操做符 还没有有功能支持 __matmul__(),还没有支持

        分界符

            ( ) [ ] { }

            , : . ; @ = ->

            += -= *= /= //= %= @=

            &= |= ^= >>= <<= **=

           

            ; 当多行语句在一行表示时,能够用分号分隔,但不建议

            -> 函数注解,辅助对函数参数及返回值类型进行注解

                def func(a:int ,b :str) ->str:

                    return "{} and {} ".format(a,b) 

                它只是一种注解,一种约定,-> 指的是返回值是str

 

                func(123,"Python")

                func("Python",123)

                输出:

                    123 and Python

                    Python and 123

        Python语法不使用的符号:

            $ ? `

 

    (3),所有内置函数  (69)

        abs()        chr()         exec()      hex()        map()        print()    staticmethod()

        all()        classmethod() filter()    id()         max()        property() str()

        any()        compile()     float()     input()      memoryview() range()    sum()

        ascii()      complex()     format()    int()        min()        repr()     super()

        bin()        delattr()     frozenset() isinstance() next()       reversed() tuple()

        bool()       dict()        getattr()   issubclass() object()     round()    type()

        breakpoint() dir()         globals()   iter()       oct()        set()      vars()

        bytearrary() divmod()      hasattr()   len()        open()       setattr()  zip()

        bytes()      enumerate()   hash()      list()       ord()        slice()    __import__()

        callable()   eval()        help()      locals()     pow()        sorted()

相关文章
相关标签/搜索