zoukankan      html  css  js  c++  java
  • day5

    第1章 Day5

    1.1 Yield

    1.1.1 yield的表达式形式的应用
    def eater(name):
        print('%s 说:我开动啦' %name)
        while True:
            food=yield
            print('%s eat %s' %(name,food))

    alex_g=eater('alex')
    print(alex_g)

    print(next(alex_g))
    print('==============>')
    print(next(alex_g))
    print('==============>')
    print(next(alex_g))

    #用法:
    def eater(name):
        print('%s 说:我开动啦' %name)
        food_list=[]
        while True:
            food=yield food_list
            food_list.append(food) #['骨头','菜汤']
           
    print('%s eat %s' %(name,food))

    alex_g=eater('alex')
    #第一阶段:初始化
    next(alex_g) #等同于alex_g.send(None)
    print('===========>')

    #第二阶段:给yield传值
    print(alex_g.send('骨头')) #1 先给当前暂停位置的yield传骨头 2 继续往下执行,直到再次碰到yield,然后暂停并且把yield后的返回值当做本次调用的返回值
    # print('===========>')
    print(alex_g.send('菜汤'))
    print(alex_g.send('狗肉包子'))

    next(alex_g)与alex_g.send('骨头') 的区别

    next(生成器)是执行一次生成器碰到yield暂停 (1,先给yield传一个None,在执行生成器,碰到yield返回None,并暂停生成器)

    生成器.send(‘x’) 先给yield的传值x 在执行一次生成器碰到yield把yield后的值x返回并暂停

    1.1.2 把初始化跟给yield传值封装函数

    可以实现两个函数相互切换 相当于cpu的上下文切换(机器里的并发效果就是这么实现的)

    def eater(name):
        print('%s
    说:我开动啦' %name)
        food_list=[]
        while True:
            food=yield food_list
            food_list.append(food) #['骨头','菜汤']
            print('%s eat %s' %(name,food))


    def producer():
        alex_g=eater('alex')
        #第一阶段:初始化
        next(alex_g)
        #第二阶段:给yield传值
        while True:
            food=input('>>: ').strip()
            if not food:continue
            print(alex_g.send(food))


    producer()

    1.1.3 给yield定义一个初始化的装饰器

    def init(func):
        def warpper(*wargs,**kwargs):
            res=func(*wargs,**kwargs)
            next(res)
            return res
        return warpper
    @init
    def eater(name):
        print('%s 说:我开动啦' %name)
        food_list=[]
        while True:
            food=yield food_list
            food_list.append(food) #['骨头','菜汤']
           
    print('%s eat %s' %(name,food))
    def producer():
        alex_g=eater('alex')
        #第二阶段:给yield传值
       
    while True:
            food=input('>>: ').strip()
            if not food:continue
           
    print(alex_g.send(food))
    producer()

    1.2 面向过程编程

    #面向过程:核心是过程二字,过程即解决问题的步骤,基于面向过程去设计程序就像是在设计
    # 一条工业流水线,是一种机械式的思维方式

    #优点:程序结构清晰,可以把复杂的问题简单化,流程化
    #缺点:可扩展性差,一条流线只是用来解决一个问题
    #应用场景:linux内核,git,httpd,shell脚本

    #grep -rl 'error' /dir/
    import os
    def init(func):
        def wrapper(*args,**kwargs):
            g=func(*args,**kwargs)
            next(g)
            return g
        return wrapper
    #第一阶段 站到文件的绝对路径
    @init
    def search(target):
        while True:
            filepath=yield
           
    g=os.walk(filepath)
            for dirpath,_,files in g:
                for file in files:
                    abs_path=r'%s\%s' %(dirpath,file)
                    target.send(abs_path)

    #第二阶段打开文件
    @init
    def opener(target):
        while True:
            abs_path=yield
            with
    open(abs_path,'rb') as f:
                target.send((abs_path,f))
    #第三阶段读出每一行
    @init
    def cat(target):
        while True:
            abs_path,f=yield
            for
    line in f:
                res=target.send((abs_path,line))
                if res:break


    #第四阶段过滤是否有关键字
    @init
    def grep(pattern,target):
        tag=False
        while True
    :
            abs_path,line=yield tag
            tag=False
            if
    pattern in line:
                target.send(abs_path)
                tag=True
    #第五阶段答应文件名
    @init
    def printer():
        while True:
            abs_path=yield
           
    print(abs_path)
    g=search(opener(cat(grep('os'.encode('utf-8'),printer()))))
    g.send(r'C:UsersAdministratorPycharmProjectspython18期day5')

    1.3 递归

    1.3.1 递归的定义

    #递归调用:在调用一个函数的过程中,直接或间接地调用了函数本身
    # 必须有明确的结束条件
    # 直接
    def func():
        print('from func')
        func()

    func()

    # 间接
    def foo():
        print('from foo')
        bar()

    def bar():
        print('from bar')
        foo()

    foo()
     

    1.3.2 递归的执行分为两个阶段:
    1 递推
    2 回溯


    l =[1, 2, [3, [4, 5, 6, [7, 8, [9, 10, [11, 12, 13, [14, 15,[16,[17,]],19]]]]]]]

    def search(l):
        for item in l:
            if type(item) is list:
                search(item)
            else:
                print(item)

    search(l)

    1.4 二分法 一种提高查找效率的算法 对于有序的可以使用

    l=[1,2,10,30,31,33,40,99,102]
    def search(l,num):
        print(l)
        if len(l)==1:
            if l[0]==num:
                print('find it')
            else:
                print('not exists')

        mid_index=len(l)//2
        mid_value=l[mid_index]
        if len(l) > 1:
            if num > mid_value:
                # in the right
               
    l=l[mid_index:]

            if num<mid_value:
                #in the left
               
    l=l[:mid_index]
            if num==mid_value:
                print('find it')
                return
           
    search(l, num)
    search(l,33)

    1.5 模块

    模块不只有自己的写的python模块  还有其他语言编写的模块

    为什么有模块 程序不可能把所有代码放在一个文件里,难以维护

    模块与python文件关系

    例如test.py test为模块名

    Python test.py test.py 为一个脚本文件

    导入模块 import test

    包也为是一种特殊的模块

    导入包 其实就是导入包里的__init__模块

    1.5.1 导入模块干了哪些事

    #1 执行源文件
    #2 以一个源文件的全局名称空间
    #3 在当前位置拿到一个模块名,指向2创建的名称空间
    函数执行时调用的名称空间在定义阶段已经定了

    调用导入的函数在执行时调用的名称空间取决于定义阶段

    1.5.2 导入方式1

    import spam
    money=100000000000
    def read1():
        print('from test')
    print(spam.money)
    print(spam.read1)
    spam.read1()

    spam.read2()
    spam.change()
    print(spam.money)

    cat sparm.py

    print('from the spam.py')

    __all__=['money','x'] #对from spam import * 有用  #*只包含money,x

    # _money=1000 #对from spam import * 有用  #*表示导入不了以下滑线开头的变量

    money=1000

    x=1

    def read1():

        print('spam->read1->money',money)

     

    def read2():

        print('spam->read2 calling read')

        read1()

    def change():

        global money

        money=0

    as 的作用

    把长的模块名变成短的

    import 模块名 as 变量名

    import spam as sl

    print(sl.money)

    # import spam as s1
    # print(s1.money)




    # sql_type=input('sql_type: ')
    # if sql_type == 'mysql':
    #     import mysql as sql
    #
    # elif sql_type == 'oracle':
    #     import oracle as sql
    #
    # sql.sqlparse()

    import sparm导入的方式

    调用时必须加前缀

    sparm.

    1.5.3 导入方式2

    from spam import money,read1,read2,change

    #优点:使用源文件内的名字时无需加前缀,使用方便
    #缺点:容易与当前文件的名称空间内的名字混淆

    不论何种导入方式 原则都一样 都遵循在哪定义的调用时还找哪的名称空间

    无论修改哪个名称空间变量的值,都不会改变另一个名称空间变量的值

    所以 不同的写法 代表调用不同名称空间的值

    from spam import money,read1,read2,change
    money=0
    print(money)
    print(read1)

    read1()

    def read1():print('ok')
    read2()

    money=10
    change()
    print(money)
    from spam import money as m
    print(m)
    from spam import *

    print(_money)
    read1()
    print(read2)

    print(money)
    print(x)
    print(read1)

    1.5.4 导入方式3

    import sparm import *

    可以选择隐藏一部分变量(sparm中的变量可能与现在文件里变量重名的可以在sparm.py文件里定义money前面加上下划线_money)

    1.5.5 导入过程

    #模块只在第一次导入时才会执行,之后的导入都是直接引用内存已经存在的结果

    import sys

    print('spam' in sys.modules) #存放的是已经加载到内的模块

    import spam

    print('spam' in sys.modules)

    # import spam

    # import spam

    # import spam

    # import spam

    # import spam

    某块的搜索路径

    import spam 寻找顺序

    1先去内存

    2先去内置模块

    3再去硬盘

    修改程序 必须重启程序才能生效 因为不重启默认冲内存加载  还是原来的代码

    了解:Importlib 可以解决不重启在修改sparm模块后自动加载  但只限于测试环境 生产环境不要用 因为不能保证其他地方没有调用此模块,其他地方有可能忘记importlib

    import time

    import importlib

    import spam

    time.sleep(20)

    import spam

    print(spam.money)

    importlib.reload(spam)

    print(spam.money)

    #结论:

    #注意:自定义的模块名一定不要与python自带的模块名重名

    #内存中--》内置模块————》sys.path

    1.5.6 模块路径与当前文件多在路径不再同一级目录时倒入时 需要添加环境变量 当前是指执行文件的路径

    import sys

    # print(sys.path)

    sys.path.insert(0,r'C:UsersAdministratorPycharmProjectspython18期周末班day5模块模块的搜索路径aaa')

    #sparm.py 在aaa 目录下

    import spam

    1.5.7 python文件的两种用途

    1. 当成脚本文件  直径用python解释器解释执行
    2. 当成模块被倒入

    import os,sys

    x=1

    def func1():

        print('from m1')

    def func2():

        print('from m2')

    def func3():

        print('from m3')

    # print(__name__)

    #文件当做脚本运行时__name__等于__main__

    #文件当做模块被加载运行时__name__等于模块名(m1) 不会执行下面的调用阶段

    if __name__ == '__main__':  #这样写即可以当做脚本文件 又可以单做模块被倒入

        #当做脚本使用

        func1()

        func2()

        func3()

          

    1.6 包package

    1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法

    2. 包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)

    3. import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件

    强调:

      1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

    2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块

    倒入文件时 sys.path第一个元素 是以执行文件 的路径为准

    1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如item.subitem.subsubitem,但都必须遵循这个原则。

    2.对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。

    3.对比import item 和from item import name的应用场景:
    如果我们想直接使用name那必须使用后者

    相对倒入与绝对倒入是相对与包来说的  .就代表当前目录 与执行文件的sys.path 路径不是一回事

    相对倒入目的防止包名版本改变

    包内部的倒入也要用相对路径,里边.代表当前目录  .. 代表上一级目录

    1.6.1 包路径与当前文件多在路径不再同一级目录时倒入时 需要添加环境变量 当前是指执行文件的路径

    import sys

    # print(sys.path)

    sys.path.insert(0,r'C:UsersAdministratorPycharmProjectspython18期周末班day5模块)

    #glance 在模块 目录下

  • 相关阅读:
    js面向对象和PHP面相对象
    git
    css3动画、2D与3D效果
    渲染数据方式
    ajax
    面向对象
    Date 日期
    Math 数值对象
    What is CGLib and JDK动态代理
    IDEA中lock对象不提示newCondition();
  • 原文地址:https://www.cnblogs.com/lieying6011/p/7274637.html
Copyright © 2011-2022 走看看