Python 学习笔记(五)
1.检查文件是否存在
我们经常需要从文件中读取数据或向其中写入数据,但要做到这一点,我们需要检查文件是否存在。
import os exists = os.path.isfile('/path/to/file')
2.读取CSV文件
import csv csv_mapping_list = [] with open("/path/to/data.csv") as my_data: csv_reader = csv.reader(my_data, delimiter=",") line_count = 0 for line in csv_reader: if line_count == 0: header = line else: row_dict = {key: value for key, value in zip(header, line)} csv_mapping_list.append(row_dict) line_count += 1
3.SQLAlchemy
SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。
关于ORM:
全称Object Relational Mapping(对象关系映射)。
特点是操纵Python对象而不是SQL查询,也就是在代码层面考虑的是对象,而不是SQL,体现的是一种程序化思维,这样使得Python程序更加简洁易读。
具体的实现方式是将数据库表转换为Python类,其中数据列作为属性,数据库操作作为方法。优点是(1)简洁易读:将数据表抽象为对象(数据模型),更直观易读;(2)可移植:封装了多种数据库引擎,面对多个数据库,操作基本一致,代码易维护;(3)更安全:有效避免SQL注入。
4.Flask-RESTful 参数解析
Flask-RESTful 内置了支持验证请求数据,它使用了一个argparse 的库。
from flask.ext.restful import reqparse
##定义解析器 parser = reqparse.RequestParser()
##添加规则,如果是必填项,还可以添加 required =true定义是否必填,通过location=['form','args'...]定义作用域 parser.add_argument('rate', type=int, help='Rate to charge for this resource')
##参数 args = parser.parse_args()
##获取指定的参数
key-name-values = args.get('XXX')
help--定义了报错时的提示信息。
5.数据格式化
Flask-RESTful 提供了 fields
模块和 marshal_with()
装饰器。类似 Django ORM 和 WTForm,可以使用 fields 模块来响应中格式化结构。
flask.ext.restful.
marshal_with
(fields, envelope=None)
A decorator that apply marshalling to the return values of your methods.
主要是解决以下报错:
TypeError:Object of type XXXX is not JSON serialzable.
导入模块的方式;
from flask.ext.restful import fields, marshal_with
案例
from collections import OrderedDict from flask.ext.restful import fields, marshal_with
###一定是字典结构 resource_fields = { 'task': fields.String, 'uri': fields.Url('todo_ep') } class TodoDao(object): def __init__(self, todo_id, task): self.todo_id = todo_id self.task = task # This field will not be sent in the response self.status = 'active' class Todo(Resource): @marshal_with(resource_fields) def get(self, **kwargs): return TodoDao(todo_id='my_todo', task='Remember the milk')
此外,fields.Nested(),fields.List()也是常用从方法。
6.Python实现多任务
进程>线程>协程
主进程:执行的时候,默认的进程称作主进程;子进程,在主进程中可以开启子进程。
multiprocessing模块提供了类似threading模块的接口,并对进程的各种操作进行了良好的封装,提供了各种进程间通信的接口例如Pipe, Queue等等,可以实现进程间的通信,同步等操作。
import time
from multiprocessing import Process
# 创建子进程p = Process(target=run, args=("Ail",)) # target进程执行的任务/函数, args传参数,可选,可迭代(元组)
#启动进程p.start()
7.进程ID
import os
os.getpid() ##当前进程ID
os.getppid() ##获取当前进程的父进程的id
8.全局变量在多个进程中不能共享
在子进程中修改全局变量对父进程中的全局变量没有影响。因为父进程在创建子进程时对全局变量做了一个备份,父进程中的全局变量与子进程的全局变量完全是不同的两个变量。全局变量在多个进程中不能共享。
即:如果是全局变量,则每个进程都会拥有一份全局变量,各自操作各自的全局变量。
9.进程join方法
有时候会需要父进程等待子进程结束再执行父进程后面的代码,此时可以考虑使用join()方法。
例子如下:
import time from multiprocessing import Process import os def run(): print("子进程开启") time.sleep(2) print("子进程结束") if __name__ == "__main__": print("父进程启动") p = Process(target=run) p.start() p.join() # 等待子进程结束后,再往下执行 print("父进程结束") # 输出结果 父进程启动 子进程开启 子进程结束 父进程结束
jion()也可以理解为阻塞主进程,此处后面的代码,主进程暂不执行。它可以设置timeout。
10.多进程process的常用方法
(1) start():启动子进程实例(创建子进程);
(2) is_alive():判断子进程是否还在活着;如果任务完成,则false;
(3) join([timeout]):是否等待子进程执行结束,或等待多少秒;
(4) terminate():不管任务是否完成,立即终止子进程;
(5) close
() :关闭 Process
对象,释放与之关联的所有资源。如果底层进程仍在运行,则会引发 ValueError
。注意,如果资源释放后(已调用colse()),再执行 is_alive()会报错。
11.进程池
如果要启动大量的子进程,可以用进程池的方式批量创建子进程。
from multiprocessing.pool import Pool
# 创建多个进程,表示可以同时执行的进程数量。默认大小是CPU的核心数
p = Pool(8)
# 创建进程,放入进程池统一管理 p.apply_async(funcation-name, funcation-args=(???,)) ###非阻塞式;还可以添加回调函数。此外还有一种阻塞式:p.apply()--注意:(1)阻塞式,进程池中一个任务
完成之后,才能开始下一个任务;(2)这个没有回调函数参数。
# 如果我们用的是进程池,在调用join()之前必须要先close(),并且在close()之后不能再继续往进程池添加新的进程(即停止添加任务)
p.close()
# 进程池对象调用join,会等待进程吃中所有的子进程结束完毕再去结束父进程
p.join()
12.进程间通信
需要使用到了multiprocessing模块的Queue(队列)。
from multiprocessing import Process, Queue q = Queue() ##创建队列 q.put('??') ##将 obj 放入队列;还有两个参数[, block[, timeout]。如果可选参数 block 是True(默认值)而且timeout是None默认值), 将会阻塞当前进程,直到有空的缓冲槽。 q.full() ##判断队列是否已满;如果队列是满的,返回True,反之返回False 。 q.qsize() ##返回队列的大致长度。由于多线程或者多进程的上下文,这个数字是不可靠的。 q.get() ##从队列中取出并返回对象。注意:先进先出。可选参数[block[, timeout]];如果可选参数 block 是True(默认值) 而且timeout是None(默认值), 将会阻塞当前进程,直到队列中出现可用的对象。
q.colse() ##指示当前进程将不会再往队列中放入对象。一旦所有缓冲区中的数据被写入管道之后,后台的线程会退出。这个方法在队列被gc回收时会自动调用。
参考
1.快速入门 — Flask-SQLAlchemy 2.0 documentation
http://www.pythondoc.com/flask-sqlalchemy/quickstart.html
2.Python3多进程multiprocessing模块的使用
https://www.jianshu.com/p/a5f10c152c20
3.multiprocessing
--- 基于进程的并行
https://docs.python.org/zh-cn/3.7/library/multiprocessing.html