python基础(五)
2018-02-13 本文已影响17人
EvanForEver
文本文件(包括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目录递归显示