python基础(五)

文本文件(包括CSV和JSON)的读写

  • open的参数(异常处理使用try…except…finally)
  • 使用with简化异常处理
  • 文件内容读取 (readline和readlines)
     f.read(size) 返回长度为size的字符串
     f.readline() 单独读取一行并在字符串末尾加个换行符,如果返回空字符串表明到文件结尾
     f.readlines() 返回一个列表,包括文件所有数据行
     f.tell() 返回一个整数代表文件对象中指针的位置
  • 文件的写入(w和a的区别)
     f.write(str) 将str写入文件
>>f = open('sample.txt', 'r') 
#  r = read, w = write, a = append, b = binary, +表示文件不存在就创建(覆盖重写)
>>texts = f.read()
>>print(texts)
>>f.close()
Line #1 hello world
Line #2 life is not easy

#按行处理文件,加快速度显示 readline和readlines
>>with open('sample.txt', 'r') as f:
>>    line = f.readline() #读取下一行
>>    while line: #判断是否到结尾
>>       print(line.strip())
>>        line = f.readline()
Line #1 hello world
Line #2 life is not easy

>>with open('sample.txt', 'r') as f:
>>    for line in f.readlines(): #一次性读取多行
>>        print(line.strip())
Line #1 hello world
Line #2 life is not easy

#文件的写入
>>texts = ['New line #1 hello world', 'Line #2 life is not easy']
>>with open('new_sample.txt', 'w+') as f: # 覆盖文件重新写入
>>    for text in texts:
>>        f.write(text + '\n') #记得加换行符
>>with open('new_sample.txt', 'a') as f: #在文件结尾写入内容
>>    f.write('Something new\n')

json与csv文件操作

  • text、json和csv只是内容格式的不同,但都是文本文件
  • 使用json库从文件读取和写入数据到文件(不加s为文件操作,加s为字符串操作)
     json.dump() 封装,把字典写入json文件 (传入的是文件句柄,而不是文件名!)
     json.load() 拆封,读取json文件,输出字典
     json.dumps() 把json对象转变为str
     json.loads() 把str(json可读取的字典格式)转变为json对象
  • 使用csv库读写csv格式文件
     csv.reader() 把文件句柄传入返回一个可迭代的对象
# json
>>import json
>>config = {'ip': '192.168.1.1', 'port': ['9100', '9101', '9102']}
>>with open('config.json', 'w+') as f:
>>    json.dump(config, f) # dump把字典写入json文件
>>with open('config.json', 'r') as f:
>>    new_config = json.load(f) 
>>print(type(new_config))
<class 'dict'>
>>print(new_config)
{'ip': '192.168.1.1', 'port': ['9100', '9101', '9102']}

#json文件相当于字典,但是里面字符串必须用双引号括起来
>>config_str = '{"ip": "192.168.1.1", "port": ["9100", "9101", "9102"]}'
>>config = json.loads(config_str)
>>print(config)
{'ip': '192.168.1.1', 'port': ['9100', '9101', '9102']}

>>new_config_str = json.dumps(config)
>>print(type(new_config_str))
<class 'str'>
>>print(new_config_str)
{"ip": "192.168.1.1", "port": ["9100", "9101", "9102"]}

序列化及应用

  • 关于序列化和反序列化
     序列化(封装):把变量从内存中变成可存储传输的过程。程序运行过程中,所有变量都在内存中,可以随时修改变量,但程序结束没有把修改的内容放入磁盘则修改无效,因此要把对象序列化到字符串或一个文件中去。
     反序列化(拆封):从文件中(字节或字符串)读取还原成对象
  • 使用pickle库读写序列化数据
>>import pickle
>>class MyObject:
>>    def __init__(self, x, y):
>>        self.x = x
>>        self.y = y

>>obj = MyObject(100, 200)
>>s_obj = pickle.dumps(obj)
>>print(s_obj)
>>obj = pickle.loads(s_obj)
>>print(obj.x, obj.y)

多进程与多线程

  • 进程与线程概念的差异
     进程:进程(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窗口下执行,获取进程的id
# notebook只支持显示当前进程的

if __name__=='__main__':
    print('Parent process %s.' % os.getpid())
    p = Process(target=run_proc, args=('test',)) #target为进程的目标函数,args是参数
    #python中括号中不加逗号会以为是函数调用
    print('Child process will start.')
    p.start() # 开始进程
    p.join() # 等待进程执行结束
    print('Child process end.')

# 多线程
import time, threading
# python没有线程id但有线程名
# 新线程执行的代码:
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)

进程池与线程池

  • 动态管理进程线程
  • 创建进程池与线程池
  • 参数传递
# 进程池
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) #电脑有多少核可以设置相应两倍的进程数
    for i in range(5): #有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

def long_op(x):
    print('%d\\n' % n)
    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()

数据共享与锁

  • 进程数据共享
# 多进程变量共享
from multiprocessing import Process, Queue
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() # 一定要结合异常处理否则可能会导致锁无法释放
    
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)

系统库

  • sys
     传递命令行参数(sys.argv获取命令行参数)
     配合argparser库高效处理参数
     路径设置(sys.path获取系统当前路径)
  • os 文件操作
     系统信息
     文件目录操作
     实现dir目录递归显示
    原文作者:Evan不被打败
    原文地址: https://www.jianshu.com/p/4e4d37b31192
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞