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 在模块 目录下

原文地址:https://www.cnblogs.com/lieying6011/p/7274637.html