本篇内容

  1. 协程函数
  2. 递归
  3. 二分法
  4. import语句
  5. from...import语句
  6. 模块搜索路径
  7. 包的导入
  8. 软件开发规范
  9. 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的更多相关文章

  1. 【Python之路】第五篇--Python基础之杂货铺

    字符串格式化 Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存. 1.百分号方式 ...

  2. 【0728 | 预习】第三篇 Python基础

    第三篇 Python基础预习 Part 1 变量 一.什么是变量? 二.为什么要有变量? 三.定义变量 四.变量的组成 五.变量名的命名规范 六.变量名的两种风格 Part 2 常量 Part 3 P ...

  3. 五、Python基础(2)

    五,Python基础(2) 1.数据类型基础 (一)什么是数据类型? 用于区分变量值的不同类型. (二)为何对数据分类? 针对不同状态就应该用不同类型的数据去标识. (三)数据类型分类 1.数字类型 ...

  4. 第五篇python进阶之深浅拷贝

    目录 第五篇python进阶之深浅拷贝 一.引言 1.1可变 和不可变 二.拷贝(只针对可变数据类型) 三.浅拷贝 四.深拷贝 第五篇python进阶之深浅拷贝 一.引言 1.1可变 和不可变 id不 ...

  5. 第五篇.python进阶

    目录 第五篇.python进阶 1. 异常处理 2. 数字类型内置方法 2.定义: 3.常用操作+内置方法: 4.存一个值or多个值: 5.有序or无序: 6.可变和不可变 1.用途: 2.定义: 3 ...

  6. 第一篇:python基础

    python基础   python基础 本节内容 python起源 python的发展史 为什么选择python3 第一个python程序 变量定义 表达式和运算符 用户输入 流程控制 判断 流程控制 ...

  7. 【Python之路】第七篇--Python基础之面向对象及相关

    面向对象基础 基础内容介绍详见一下两篇博文: 面向对象初级篇 面向对象进阶篇 其他相关 一.isinstance(obj, cls) 检查obj是否是类 cls 的对象 class Foo(objec ...

  8. 【Python之路】第六篇--Python基础之模块

    模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...

  9. 【Python之路】第九篇--Python基础之线程、进程和协程

    进程与线程之间的关系 线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一内存空间,当进程退出时该进程所产生的线程都会被强制退出并清除.线程可与属于同一进程的其它线程共享进程所拥有的全 ...

随机推荐

  1. 【洛谷1580】yyy loves Easter_Egg I(字符串处理题)

    点此看题面 大致题意: 略.(一道模拟题,自己去看题面吧) 几个字符数组函数 纯粹是一道字符串处理题,就当是学了一下各种与字符数组相关的函数吧! \(gets()\):这个是比较常用的函数,就是读入一 ...

  2. 棋盘V(最小费用最大流)

    棋盘V 时间限制: 1 Sec  内存限制: 128 MB提交: 380  解决: 44[提交] [状态] [讨论版] [命题人:admin] 题目描述 有一块棋盘,棋盘的边长为100000,行和列的 ...

  3. Object类和String类

    Object类 Object类是Java语言中的根类,即所有类的父类. equals方法 返回值类型为:boolean类型 用于比较两个对象是否相同,它其实就是使用两个对象的内存地址在比较. 例子: ...

  4. AngularJS1.X版本双向绑定九问

    前言 由于工作的原因,使用angular1.x版本已经有一段时间了,虽然angualr2升级后就完全重构了,但每个版本存在也有一定的道理.话不多说,进入正题. 1.双向绑定的原理是什么? Angual ...

  5. 【线性基 集合hash】uoj#138. 【UER #3】开学前的涂鸦

    还需要加强分析题目特殊性质,设计对应特殊算法,少想多写大力dfs剪枝不要管MLETLE直接上的能力 红包是一个有艺术细胞的男孩子. 红包由于NOI惨挂心情不好,暑假作业又多,于是他开始在作业本上涂鸦. ...

  6. Java 获取Web项目相对webapp地址

    例如, import java.io.File; import java.io.FileInputStream; import javax.servlet.http.HttpServletReques ...

  7. 认识mysql(4)

    今日是MySQL的第四篇,难度会稍微加大,加油! 开始吧! 1.外键(foreign  key) 1.定义:让当前表字段的值在另一个表的范围内选择 2.语法: foreign key(参考字段名) r ...

  8. jsp--提交表单→插入数据库→成功后返回提示信息

    <%@ page language="java" import="java.util.*,java.sql.*" pageEncoding="u ...

  9. mysql的性能优化案例

    在一次项目实现中,以前写了个程序,将在txt文件中的电话号码和对应的类型往数据库中插入,小数据量的情况下,用个数组遍历循环的方式,很容易解决,但是当数据量一下 但是,几十万个电话一次性插入,就变得耗时 ...

  10. JZOJ 5196. 【NOIP2017提高组模拟7.3】B

    5196. [NOIP2017提高组模拟7.3]B Time Limits: 1000 ms  Memory Limits: 262144 KB  Detailed Limits   Goto Pro ...