Python总结笔记(六)文件和多线程
- 文本文件读写
- json与csv文件操作
- 序列化及应用
- 多进程与多线程
- 进程池与线程池
- 数据共享与锁
- 系统库
1. 文本文件读写
■open的参数 f = open('sample.txt', 'r') # r = read, w = write, a = append, b = binary, +表示文件不存在就创建(覆盖重写)
■使用with简化异常处理:with不管是否出现异常,文件最后都关闭。
■文件内容读取:f.readlines,一行一行读,将每行最后一个换行符读入
f = open('sample.txt', 'r') # r = read, w = write, a = append, b = binary, +表示文件不存在就创建(覆盖重写)
texts = f.read()
print(texts)
f.close()
with open('sample.txt', 'r') as f: #with:不管是否出现异常,文件最后都关闭
line = f.readline()#按行读取
while line:
print(line.strip())
line = f.readline()
with open('sample.txt', 'r') as f:
for line in f.readlines():#简化readline——for循环可以f.readlines,一行一行读,将每行最后一个换行符读入
print(line.strip())#将最后一个回车换行吃掉
# 实现readlines生成器
def readlines(f):
line = f.readline()
while line:
yield line
line = f.readline()
with open('sample.txt', 'r') as f:
for line in readlines(f):
print(line.strip())
2. json与csv文件操作
■使用json库 (python的字典数据,特殊地方在于:字符串用‘ ’ 引号扩起来) 从文件读取和写入数据到文件:
文件读取:
json.load()——将文件变成json对象
json.loads()——读取内容,将字符串转换成json字典对象
写入数据到文件:
json.dump()——将json类型变成文件对象
json.dumps()——将json类型变成字符串对象
■使用csv库读写csv格式文件
# json文件:python的字典数据,特殊地方在于:字符串用‘ ’ 引号扩起来
import json
config = {'ip': '192.168.1.1', 'port': ['9100', '9101', '9102']}
with open('config.json', 'w+') as f:
json.dump(config, f) #json.dump()——将json类型变成文件对象,字典写入json文件
with open('config.json', 'r') as f:
new_config = json.load(f)#json.load()——将文件变成json对象
print(type(new_config))#字典类型
print(new_config)
config_str = '{"ip": "192.168.1.1", "port": ["9100", "9101", "9102"]}'
config = json.loads(config_str)#json.loads()——读取内容,将字符串转换成json字典对象
print(config)
new_config_str = json.dumps(config) #json.dumps()——将json类型变成字符串对象
print(type(new_config_str)) #字符串类型
print(new_config_str)
# csv
import csv
feature_list = [] #特征
label_list = [] #读label
with open('sales.csv','r') as f:
reader = csv.reader(f)
headers = next(reader)#标题,先取第一行——对headers进行处理
for row in reader:
label_list.append(row[-1])#最后一列
row_dict = {}
for i in range(1, len(row) - 1):#第二列到倒数第二列
row_dict[headers[i]] = row[i]
feature_list.append(row_dict)
print(feature_list)
print(label_list)
3. 序列化及应用
■关于序列化和反序列化import pickle#将对象序列化到字符串或者文件中。
■使用pickle库读写序列化数据
pickle.dumps()将对象写入文件中——序列化
pickle.loads()从文件读出对象——反序列化
# 序列化与反序列化
import pickle#将对象序列化到字符串或者文件中。
class MyObject:
def __init__(self, x, y):
self.x = x
self.y = y
obj = MyObject(100, 200)
s_obj = pickle.dumps(obj)#pickle.dumps()将对象写入文件中——序列化
print(s_obj)
obj = pickle.loads(s_obj)#pickle.loads()从文件读出对象——反序列化
print(obj.x, obj.y)
4. 多进程与多线程
■进程与线程概念的差异:
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。
线程:线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。 一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。
■创建进程与线程
■参数传递
# 多进程
from multiprocessing import Process
import os
# 子进程要执行的代码
def run_proc(name):
print('Run child process %s (%s)...' % (name, os.getpid())) # 复制到文件然后在cmd窗口下执行
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Process(target=run_proc, args=('test',))#args=('test',)加逗号 不加,会认为是函数调用。
print('Child process will start.')
p.start()
p.join()
print('Child process end.')#只显示当前进程的,子进程不显示
# 多线程
import time, threading
# 新线程执行的代码:
def loop():
print('thread %s is running...' % threading.current_thread().name)
n = 0
while n < 5:
n = n + 1
print('thread %s >>> %s' % (threading.current_thread().name, n))
time.sleep(1)
print('thread %s ended.' % threading.current_thread().name)
print('thread %s is running...' % threading.current_thread().name)
t = threading.Thread(target=loop, name='LoopThread')#线程起名字
t.start()#启动线程
t.join()#等待线程执行结束
print('thread %s ended.' % threading.current_thread().name)
5. 进程池与线程池
■动态管理进程线程的挑战
■创建进程池与线程池
■参数传递
# 进程池Pool
from multiprocessing import Pool
import os, time, random
def long_time_task(name):
print('Run task %s (%s)...' % (name, os.getpid()))
start = time.time()
time.sleep(random.random() * 3)
end = time.time()
print('Task %s runs %0.2f seconds.' % (name, (end - start)))
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Pool(4) #进程最多跑4个。8核可以跑8-10个进程
for i in range(5):
p.apply_async(long_time_task, args=(i,))
print('Waiting for all subprocesses done...')
p.close()#进程池不可以添加新任务
p.join()#等所有任务结束
print('All subprocesses done.')
# 线程池
import threadpool
import time,os
def long_op(x):
print('%d\\n' % x)
time.sleep(2)
pool = threadpool.ThreadPool(os.cpu_count())
tasks = threadpool.makeRequests(long_op, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) # 可以尝试函数使用多个参数,必须看源代码
print(len(tasks))
[pool.putRequest(task) for task in tasks]
pool.wait()
- 练习:找最大的三个数最快的方法?
# 多线程的应用--找最大的第三个数
def top3(data):
data.sort()
temp_result[threading.current_thread().name] = data[-3:]
data_set = [[1, 7, 8, 9, 20, 11, 14, 15],
[19, 21, 23, 24, 45, 12, 45, 56, 31],
[18, 28, 64, 22, 17, 28]]
temp_result = {}
threads = []
for i in range(len(data_set)):
t = threading.Thread(target=top3, name=int(i), args=(data_set[i], ))
threads.append(t)
for t in threads:
t.start()
for t in threads:
t.join()
result = []
for k, v in temp_result.items():
result.extend(v)
result.sort()
print(result[-3:])
6. 数据共享与锁
■进程数据共享import Process, Queue #Queue多进程变量共享:跨进程
■线程数据共享
■锁,如何安全的加锁?——在读写文件时,别人不可动文件
# 多进程变量共享
from multiprocessing import Process, Queue#Queue多进程变量共享:跨进程 , radis实现分布式队列
import os, time, random
def write(q):
print('Write: %s' % os.getpid())
for value in ['AAA', 'BBB', 'Hello World']:
print('Write %s' % value)
q.put(value)
time.sleep(random.random())
def read(q):
print('Read: %s' % os.getpid())
while True:
value = q.get(True)
print('Read %s' % value)
if __name__ == '__main__':
q = Queue()
pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))
pw.start()
pr.start()
pw.join()
time.sleep(3)
pr.terminate()#强制结束
print('Done')
# 锁 --在读写文件时,别人不可动文件
import threading
lock = threading.Lock()
balance = 0
def change_balance(n):
global balance
balance += n
# balance = 100,但是两个进程,1个加10,一个加20,同时操作,最后balance可能变成110,也可能变成120,
# 但不是我们要的130。
def run_thread(n):
lock.acquire()#获得锁
try:
change_balance(n)
except:
pass
finally:
lock.release()#用完后realease
threads = []
for i in range(11):
t = threading.Thread(target=run_thread, args=(i, ))
threads.append(t)
for t in threads:
t.start()
for t in threads:
t.join()
print(balance)
7. 系统库
■sys
传递命令行参数sys.argv#看命令行参数
配合argparser库高效处理参数
路径设置sys.path#系统当前路径
# sys应用
import sys
print(sys.argv)#看命令行参数:notebook入口
print(sys.path)#系统当前路径
# sys.path.append(...)
■os
系统信息
文件目录操作
实现dir目录递归显示
# os应用
# 关键部分:os.listdir, os.path.abspath/isdir/join
import os
#文件操作popen,getcwd
#dir()os
def dir_s(path, tabs=0):
path = os.path.abspath(path)#获取绝对目录
files= os.listdir(path) #得到文件夹下的所有文件名称
print(files)
my_dirs = []
for f in files:
abs_path = os.path.join(path, f)
if os.path.isdir(abs_path):
my_dirs.append(f)
else:
print('\t' * tabs + f)
for my_dir in my_dirs:
print('\t' * tabs + my_dir)
dir_s(os.path.join(path, my_dir), tabs + 1)
dir_s('.') # 尝试walk函数更简单的实现