码迷,mamicode.com
首页 > 编程语言 > 详细

python 第五天

时间:2017-08-03 12:38:26      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:协程函数、模块、包


第一:

1、协程函数:

yield 是把函数的结果作为一个生成器。

一个对象如果有iter和next方法,说明这个对象是一个迭代器、迭代器也是生成器。

如果一个对象只有iter方法,那么这个对象是一个可迭代的对象。

yield就是把函数的执行结果封装好iter和next方法、即可得到一个迭代器。

他的功能和return功能类似、都可以返回值、但是不同的是return只能返回一次值、而yield可以返回多次值。

函数暂停与运行的状态是又yield保存。

例1、

#yield

def func(count):

    print(‘start‘)

    while True:

        yield   count

        count+=1

g=func(10)

print(g)

print(next(g))

print(next(g))


例2:

#yield的表达式应用。

def eater(name):

    print(‘%s 说:我开动了‘ %name)

    while True:

        food=yield

        print(‘%s eat %s‘ %(name,food))


res=eater(‘xz‘)

print(next(res))

print(‘================‘)

res1=next(res)

print(res1)

>>

xz 说:我开动了

None

================

xz eat None

Non


#yield的表达式、执行前必须先初始化、或者传值none

#yield的表达式应用。

def eater(name):

    print(‘%s 说:我开动了‘ %name)

    while True:

        food=yield

        print(‘%s 吃 %s‘ %(name,food))


res=eater(‘xz‘)

#第一阶段初始化,让生成器初始到一个位置

next(res)**next的目的就是给yield一个none值

#第二阶段、给yield传值

res.send(‘包子‘)

>>

xz 说:我开动了

xz 吃 包子

xz 吃 骨头


例3:

#yield的表达式应用。

def eater(name):

    print(‘%s 说:我开动了‘ %name)

    food_list=[]

    while True:

        food=yield food_list

        print(‘%s 吃 %s‘ %(name,food))

        food_list.append(food)

res=eater(‘xz‘)

#第一阶段初始化,让生成器初始到一个位置

# next(res)

res.send(None)

#第二阶段、给yield传值

print(res.send(‘包子‘))

print(res.send(‘菜汤‘))

>>

xz 说:我开动了

xz 吃 包子

[‘包子‘]

xz 吃 菜汤

[‘包子‘, ‘菜汤‘]


例4:

#yield的表达式应用。

def eater(name):

    print(‘%s 说:我开动了‘ %name)

    food_list=[]

    while True:

        food=yield food_list

        print(‘%s 吃 %s‘ %(name,food))

        food_list.append(food)


def func():

    res=eater(‘xiaozhang‘)

    next(res)

    while True:

        food_inp=input(‘>>‘).strip()

        if not  food_inp:continue

        res1=res.send(food_inp)

        print(res1)

func()

>>

xiaozhang 说:我开动了

>>菜汤

xiaozhang 吃 菜汤

[‘菜汤‘]

>>


#装饰器解决初始化的问题:

def init(func):

    def warpper(*args,**kwargs):

        res=func(*args,**kwargs)

        next(res)

        return res

    return warpper


@init

def eater(name):

    print(‘%s 说:我开动了‘ %name)

    food_list=[]

    while True:

        food=yield food_list

        print(‘%s 吃 %s‘ %(name,food))

        food_list.append(food)


def func1():

    res=eater(‘xiaozhang‘)

    while True:

        food_inp=input(‘>>‘).strip()

        if not  food_inp:continue

        res1=res.send(food_inp)

        print(res1)

func1()


2、面向过程:核心是过程二字、过程即解决问题的步骤。

基于面向过程去设计程序就像一条工业流水线、是一种机械式的思维。

优点:程序结构清晰、易读、流程化

缺点:可扩展性差、一条流程线只解决一个问题

应用场景:linux内核……、功能单一


例1:使用面向过程的方法、实现grep -lr ‘error‘ /dir/#显示文件中有error的列表文件


import os

def init(func):

    def warpper(*args,**kwargs):

        res=func(*args,**kwargs)

        next(res)

        return res

    return warpper


第一阶段:找到文件的决定路径

@init

def search(target):

    while True:

        filepath=yield

        g=os.walk(filepath)

        for pardir,_,files in g:

            for file in files:

                abspath=r‘%s\%s‘ %(pardir,file)

                target.send(abspath)


第二阶段:打开文件

@init

def opener(target):

    while True:

        abspath=yield

        with open(abspath,‘rb‘) as f:

            target.send((abspath,f))


第三阶段:循环读

@init

def cat(target):

    while True:

        abspath,f=yield

        for line in f:

            res=target.send((abspath,line))

            if res:break


第四阶段:过滤

@init

def grep(patten,target):

    tag=False

    while True:

        abspath,line=yield tag

        tag = False

        if patten in line:

            target.send(abspath)

            tag=True


第五阶段:打印该行属于的文件名

@init

def printer():

    while True:

        abspath=yield

        print(abspath)

g = search(opener(cat(grep(‘error‘.encode(‘utf-8‘), printer()))))

g.send(r‘H:\test‘)


3、递归函数:

在一个函数的调用过程中、直接或者间接的调用了函数本身。

递归效率比较低。

#直接

def func():

    print(‘from func‘)

    func()

func()


#间接

def foo():

    print(‘from foo‘)

    bar()


def bar():

    print(‘from bar‘)

    foo()

foo()


#递归

def age(n):

    if n == 1:

        return 18

    else:

        return (age(n-1)+2)


print(age(5))


递归必须有一个明确的条件、python没有伪递归


#递归

l=[1,3,[11,33],[11,[12,23,[44]]]]

def search(l):

    for item in l:

        if type(item) is list:

            search(item)

        else:

            print(item)

search(l)


#二分法

l = [1,2,7,7,10,31,44,47,56,99,102,130,240]

#怎么判断某一个数字是否在列表内?


def binary_search(l,num):

    print(l)

    if len(l) > 1:

        mid_index=len(l)//2

        if num > l[mid_index]:

            l=l[mid_index:]

            binary_search(l,num)

        elif num < l[mid_index]:

            l=l[:mid_index]

            binary_search(l,num)

        else:

            print(‘find it‘)

    else:

        if l[0] == num:

            print(‘find it‘)

        else:

            print(‘not exit‘)

        return

binary_search(l,32)


第二、模块与包

1、模块就是包含一个了python定义和声明的文件、文件名就是模块名字加上py的后缀。

2、 模块被导入默认就是执行模块文件

3、导入模块干了那些事:

A、执行源文件

B、以原文件产生一个全局名称空间

C、在当前位置拿到一个模块名指向2创建的名称空间


4、from ....import

A、优点:形式上不用使用源文件内的名字时无需加前缀,使用方便

B、缺点:容易与当前文件的名称空间内的名字混淆。

C、横杠只是对*起作用。有隐藏作用、可以使用__all__=[] 控制*的范围。


5、模块的加载

A、模块只是在第一次导入的时候才会执行,之后都是直接引用内存中已经加载的。

import sys

print(sys.modules)  #存放的是已经加载到内存的模块字典


模块的寻找顺序:

内存中==>内置模块==>sys.path

自定义的模块不能与py自带的模块重名。

一个py文件有2中用途、脚本和模块。

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

py文件当做模块调用时:__name__等于模块名

包就是模块的另一种模式、包下面有一个_init_.py的文件夹,就是包。

但是在这仅仅是py2.x的定义,在py3.x中没有_init_.py文件的文件夹也是包。


B、无论是import还是from....import导入、只要遇到点(.)这都是包才有的导入语法、点的左面一定是一个包。

包即模块、导入包就是导入模块。

os模块:

os.path.abspath(__file__)#获取当前文件的绝对路径。


6、日志模块的参数:

filename:指创建filehandler

filemode:文件打开的方式:默认为a可以指定为w

format:值handle使用的日志显示格式。

datefmt:指定日期时间格式。

level:设置日志的级别

stream:用指定的stream创建streamHandler、


日志的格式:

%(name)s logger的名字、并非用户名

%(levelno)s 数字形式的日志级别

%(levelnames)s  文本形式的日志级别

%(pathname)s  调用日志输出函数的模块的完整路径、可能没有

%(filename)s  调用日志输出函数的模块的文件名

%(module)s 调用日志输出函数的模块名

%(funcName)s 调用日志输出函数的函数名

%(lineno)s 调用日志输出函数的语句所在代码行

%(created)f 当前时间、用UNIX的标准时间的浮点表示

%(relativeCreated)d  输出日志信息时、自logger创建以来的毫秒数

%(asctime)s 字符串形式的当前时间、默认格式是"2003-07-08 16:44:22,234"逗号后面的是毫秒

%(thread)d 线程ID、可能咩有

%(threadName)s 线程名、可能无

%(process)d 进程ID、可能无

%(message)s 用户输出的消息


6、python正则:

\w 匹配字母数字下及划线

\W 匹配非字母数字下划线

\s 匹配任意空白字符、等价于[\t\n\r\f]

\S 匹配任意非空字符

\d 匹配任意数字、等价于[0-9]

\D 匹配任意非数字

\A 匹配字符串开始

\Z 匹配字符串的结束、如果是存在换行、只匹配到换行钱的结束字符串。

\z 匹配字符串结束

\G 匹配最后匹配完成的位置

\n 匹配一个换行符

\t 匹配一个制表符

^  匹配字符串的开头

$  匹配字符串的结尾

.  匹配任意字符、除了换行符、当re.DOTALL标记被指定时、则可以匹配包括换行符的任意字符。

[..] 用来表示一组字符、单独列出[amk]、匹配a或者m或者k

[^..] 不在[]中的字符、[^123] 匹配除了123之外的数字

*  匹配0个或者多个表达式

+  匹配一次或者多次表达式

? 匹配0次或者1次表达式

{n} 匹配n次表达式

{n,m} 匹配n次到m次表达式

a|b  匹配a或者b

() 匹配括号内的表达式、也表示一个组。


本文出自 “男儿该自强” 博客,请务必保留此出处http://nrgzq.blog.51cto.com/11885040/1953216

python 第五天

标签:协程函数、模块、包

原文地址:http://nrgzq.blog.51cto.com/11885040/1953216

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!