(六)Python总结笔记:文件和多线程

Python总结笔记(六)文件和多线程

  1. 文本文件读写
  2. json与csv文件操作
  3. 序列化及应用
  4. 多进程与多线程
  5. 进程池与线程池
  6. 数据共享与锁
  7. 系统库

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函数更简单的实现

练习:在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Laura_Wangzx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值