第五篇:python基础_5
本篇内容
- 协程函数
- 递归
- 二分法
- import语句
- from...import语句
- 模块搜索路径
- 包的导入
- 软件开发规范
- logging模块的使用
一、 协程函数
1.定义
协程函数就是使用了yield表达式形式的生成器。
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei def eater(name):
print("%s eat food" %name)
while True:
food = yield g = eater("yanglei")
print(g)
2.执行过程
运行协程函数,要先next(),对协程函数进行初始化函数,然后再send() ,send会给yield传一个值。
next()与send()的区别:
next():让函数初始化。
send():触发下一次代码的执行时,会给yield赋值。
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei 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('xiaolan')
next(alex_g)
while True:
food=input('>>: ').strip()
if not food:continue
print(alex_g.send(food)) producer()
3.装饰器扩展
协程函数与装饰器的结合,可以避免忘记初始化函数
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei def init(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs)
next(res)
return res
return wrapper @init
def eater(name):
print("%s eat food" %name)
food_list=[]
while True:
food = yield food_list
print("%s star to eat %s" %(name,food))
food_list.append(food) g = eater("xiaolan") print(g.send("火锅"))
print(g.send("烤肉"))
print(g.send("烤鱼"))
4.面向过程应用
面向过程:核心是过程二字,过程即解决问题的步骤,基于面向过程去设计程序就像是在设计一条工业流水线,是一种机械式的思维方式。
优点:程序结构清晰,可以把复杂的问题简单化,流程化。
缺点:可扩展性差,一条流线只是用来解决一个问题。
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei #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 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 #(abspath,f)
for line in f:
res=target.send((abspath,line))
if res:break #第四阶段:过滤
@init
def grep(pattern,target):
tag=False
while True:
abspath,line=yield tag
tag=False
if pattern 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'F:\python\s18')
二、 递归
1.递归调用
在调用一个函数的过程中,直接或间接地调用了函数本身,我们称为递归的调用。
(1)直接调用
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei def func():
print('the is func')
func() func()
(2)间接调用
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei def foo():
print('the is foo')
bar() def bar():
print('the is bar')
foo() foo()
2.递归的执行
递归的执行分为两个阶段递推和回溯。
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei def age(n):
if n == 1:
return 18
return age(n-1)+2 print(age(5))

三、 二分法
算法:当数据量很大适宜采用该方法。采用二分法查找时,数据需是排好序的。主要思想是:(设查找的数组区间为array[low, high])。
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei l = [1,2,5,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]:
#in the right
l=l[mid_index:]
binary_search(l,num)
elif num < l[mid_index]:
#in the left
l=l[:mid_index]
binary_search(l,num)
else:
print('find it')
else:
if l[0] == num:
print('find it')
else:
print('not exist')
return binary_search(l,31)
四、import语句
1.执行源文件。
2.以一个源文件的全局名称空间。
3.在当前位置拿到一个模块名,指向2创建的名称空间。
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei print('from the spam.py')
money=0
x=1
def read1():
print('spam->read1->money',money) def read2():
print('spam->read2 calling read')
read1() def change():
global money
money=0
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei import spam money=100000000000
def read1():
print('from test') print(spam.money)
print(spam.read1)
spam.read1() spam.read2()
spam.change()
print(money)
spam.read1() import spam as s1
print(s1.money)
五、from...import语句
优点:使用源文件内的名字时无需加前缀,使用方便。
缺点:容易与当前文件的名称空间内的名字混淆。
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei print('from the spam.py')
money=0
x=1
def read1():
print('spam->read1->money',money) def read2():
print('spam->read2 calling read')
read1() def change():
global money
money=0
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei 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)
六、模块搜索路径
注意:自定义的模块名一定不要与python自带的模块名重名
内存中---> 内置模块---> sys.path
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei print('from the spam.py')
money=0
x=1
def read1():
print('spam->read1->money',money) def read2():
print('spam->read2 calling read')
read1() def change():
global money
money=0
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei import time
import importlib import spam
time.sleep(20)
import spam
print(spam.money) importlib.reload(spam)
print(spam.money) import sys
print('time' in sys.modules)
import time
print('time' in sys.modules)
当spam在别的路径时
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei import sys
# print(sys.path)
sys.path.insert(0,r'F:\python\s18\day5\test') import spam
七、包的导入
(1)无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法
(2)包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)
(3)import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件
1.绝对导入
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei import sys
print(sys.path)
sys.path.append(r'F:\python\s18\day5')
import aaa print(aaa)
print(aaa.x)
print(aaa.y) aaa.m1.func1() aaa.bbb.m3.func3() aaa.func1()
aaa.func2()
aaa.func3() import aaa.bbb.m3 as abm
abm.func3()
2.相对导入
#!/usr/binl/env python
#encoding: utf-8
#author: YangLei import sys
sys.path.append(r'C:\Users\Administrator\PycharmProjects\python18期周末班\day5\a') import glance_v1 glance_v1.get()
glance_v1.create_resource('test.conf')
glance_v1.main()
glance_v1.register_models('mysql')
八、软件开发规范

以项目来命名,项目文件夹中要包含bin文件夹、conf文件夹、core文件夹、db文件夹、lib文件夹、log文件夹和readme。
九、logging模块的使用
1.使用方法
(1)如果不指定filename,则默认打印到终端
(2)指定日志级别:
指定方式:
1:level=10
2:level=logging.ERROR
日志级别种类:
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
(3)指定日志级别为ERROR,则只有ERROR及其以上级别的日志会被打印
logging.basicConfig(filename='access.log',
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level=10) logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
logging.log(10,'log')
2.自定义logging
"""
logging配置
""" import os
import logging.config # 定义三种日志输出格式 开始 standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字 simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s' # 定义日志输出格式 结束 logfile_dir = os.path.dirname(os.path.abspath(__file__)) # log文件的目录 logfile_name = 'all2.log' # log文件名 # 如果不存在定义的日志目录就创建一个
if not os.path.isdir(logfile_dir):
os.mkdir(logfile_dir) # log文件的全路径
logfile_path = os.path.join(logfile_dir, logfile_name) # log配置字典
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
},
'filters': {},
'handlers': {
#打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
#打印到文件的日志,收集info及以上的日志
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024*1024*5, # 日志大小 5M
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
},
'loggers': {
#logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
},
},
} def load_my_logging_cfg():
logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置
logger = logging.getLogger(__name__) # 生成一个log实例
logger.info('It works!') # 记录该文件的运行状态 if __name__ == '__main__':
load_my_logging_cfg() logging配置文件
第五篇:python基础_5的更多相关文章
- 【Python之路】第五篇--Python基础之杂货铺
字符串格式化 Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存. 1.百分号方式 ...
- 【0728 | 预习】第三篇 Python基础
第三篇 Python基础预习 Part 1 变量 一.什么是变量? 二.为什么要有变量? 三.定义变量 四.变量的组成 五.变量名的命名规范 六.变量名的两种风格 Part 2 常量 Part 3 P ...
- 五、Python基础(2)
五,Python基础(2) 1.数据类型基础 (一)什么是数据类型? 用于区分变量值的不同类型. (二)为何对数据分类? 针对不同状态就应该用不同类型的数据去标识. (三)数据类型分类 1.数字类型 ...
- 第五篇python进阶之深浅拷贝
目录 第五篇python进阶之深浅拷贝 一.引言 1.1可变 和不可变 二.拷贝(只针对可变数据类型) 三.浅拷贝 四.深拷贝 第五篇python进阶之深浅拷贝 一.引言 1.1可变 和不可变 id不 ...
- 第五篇.python进阶
目录 第五篇.python进阶 1. 异常处理 2. 数字类型内置方法 2.定义: 3.常用操作+内置方法: 4.存一个值or多个值: 5.有序or无序: 6.可变和不可变 1.用途: 2.定义: 3 ...
- 第一篇:python基础
python基础 python基础 本节内容 python起源 python的发展史 为什么选择python3 第一个python程序 变量定义 表达式和运算符 用户输入 流程控制 判断 流程控制 ...
- 【Python之路】第七篇--Python基础之面向对象及相关
面向对象基础 基础内容介绍详见一下两篇博文: 面向对象初级篇 面向对象进阶篇 其他相关 一.isinstance(obj, cls) 检查obj是否是类 cls 的对象 class Foo(objec ...
- 【Python之路】第六篇--Python基础之模块
模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...
- 【Python之路】第九篇--Python基础之线程、进程和协程
进程与线程之间的关系 线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一内存空间,当进程退出时该进程所产生的线程都会被强制退出并清除.线程可与属于同一进程的其它线程共享进程所拥有的全 ...
随机推荐
- IOS tabelView退出键盘
/** *当开始拖拽表格的时候就会调用 * */ -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { //退出键盘 [sel ...
- 解决ssh登录慢,等待时间长的问题
有时候在ssh远程登录到其他主机上时发现登录时间太长,经过亲自测试,发现主要有两个问题会导致ssh登录慢: 1.使用了dns反查,这样的话当ssh某个IP时,系统会试图通过DNS反查相对应的域名,如果 ...
- java从键盘输入学生成绩,找出最高分,并输出学生成绩等级。
/*从键盘输入学生成绩,找出最高分,并输出学生成绩等级:成绩 >=最高分-10 等级为A成绩 >=最高分-20 等级为B成绩 >=最高分-30 等级为C其余为 等级为D 提示:先输入 ...
- Oracle 数据处理
1. 对维度按照度量值的排名进行统计得分,第一名100分,第二名99分,第三名98……可以先进行排名,然后用 得分值+1,减去排名既是所得分数. -- 建表 create table province ...
- mysql查看版本,编码
SELECT * FROM gps_gpsinfo t WHERE t.reportdate < TO_DATE('2019/4/28 10:05:07', 'yyyy-MM-dd hh24:m ...
- java面试题:如果一串字符如"aaaabbc中国1512"要分别统计英文字符的数量,中文字符的数量,和数字字符的数量,假设字符中没有中文字符、英文字符、数字字符之外的其他特殊字符。
package com.swift; public class TotalNumber_String { public static void main(String[] args) { /* * 如 ...
- IDEA注释模板设置
1. 文件注释 1.1 Java类文件注释 Setting -> Editor -> File and Code Templates -> Includes -> File H ...
- require.js模块化开发
模块化开发的原因: 1.引入的js过多然后在加载的过程中容易出现假死的状态,导致页面会发生白屏 2.变量名的问题 在多人协作开发的时候容易出现变量名的冲突 面向对象 3.引入优先级的问题 模块化开发分 ...
- java 获取request中的请求参数
1.get 和 post请求方式 (1)request.getParameterNames(); 获取所有参数key后.遍历request.getParameter(key)获取value (2)re ...
- Java 数值计算精度问题
最近刚好做到涉及金额方面的项目,不像普通in,double,floatt类型来修饰,而是用BigDecimal来修饰,就去收集下了这方面的资料,整理如下: 1.float和double只能用来做科学计 ...