滴~ 今日打卡! 之前已经看了python的基础语法,学会写一些比较简单的测试脚本了,今天来看一下深入一点的I/O编程,乱入一个python列表生成器的知识点
1. 列表生成器
例如:要生成[1*1,2*2,3*3,...10*10]
[x * x for x in range(1,11)] 把要生成的元素x*x放在前面,后面跟for循环创建list
把[]改为()就是创建一个迭代器。迭代器保存的是算法,调用next()可以计算下一个元素,通常使用迭代计算。如:
G=(x*x for x in range(10))
For n in g:
Print(n)
1. Python I/O编程
(1)文件读写
With语句自动调用close()方法:
with open(‘文件路径’,’打开模式r’) as f:
//打开模式有r(读)、rb(读二进制文件,如图片、视频等)、w(写)、wb(写二进制文件)、a(追加)
f.read() #read方法一次性读取文件全部内容到内存,如果文件过大,不适宜用read方法,容易爆内存。可以反复调用read(size)方法,每次最多读取size个字节内容
f.readline() #readline方法每次读取一行内容
f.readlines() #readlines方法一次读取所有内容并按行返回list
Tip:文件很小,调用read(),如果不确定文件大小,反复调用read(size)比较保险,如果是配置文件,调用readlines()
(2)StringIO,在内存中读写str
from io import StringIO
f = StringIO()
f.write(‘python’)
F.getvalue() #获取写入后的str
(3)BytesIO,操作二进制数据
from io import BytesIO
f = BytesIO()
f.write(‘中文’,encode(‘utf-8’))
F.getvalue() #获取写入后的str
(4)操作文件和目录
os.path.abspath(‘.’) #获取当前目录的绝对路径
os.path.join(‘路径’,’新目录名’) #在某个目录下创建一个新目录
os.mkdir(‘目录名’) #创建一个新目录
os.rmdir(‘目录名’) #删除一个目录
os.path.split(‘路径/文件名’) #吧路径拆分为两部分,最后一部分总是最后级别的目录或文件名
os.path.splitext(‘文件名’) #可以获取文件扩展名
2. 进程和线程
(1)多进程:
创建子进程:使用multprocessing模块中的Process类
From multiprocessing import Process
Def proc(name):
Print(‘child process is running’)
If __name__==’__main__’:
P=Process(target=proc.args=’test’) #创建一个process实例,传入一个执行函数和函数的参数
P.start() #启动子进程
P.join()
使用进程池批量创建子进程:
from multiprocessing import Poolimport 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) #pool大小是4,最多同时执行4个进程,pool默认大小是CPU核数
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.')
Join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。调用join()之前必须先调用close()
(2)多线程:
创建线程:把一个函数传入并创建thread实例,然后调用start()开始执行
Import time,threading
Def proc():
Print(‘child process is running’)
T=threading.Thread(target=proc,name=’test’) #创建子线程并指定子线程名称
T.start()
T.join()
多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,所以,要避免多线程同时操作同一个变量
lock = threading Lock()
lock.acquire() #多个线程同时执行时,只有一个线程能成功获取锁
Try:
修改变量
finally:
lock.release() #释放锁
注意:操作完后必须释放锁,否则等待锁的线程将成为死线程
另外一种解决方式是使用ThreadLocal
local_school=threading local() #创建全局threadLocal对象
def process_student()
n=local_school.student #获取当前线程关联的name
def process_thread(name):
local_school.student=name #绑定ThreadLocal的student
Process_student()
上面的代码通过ThreadLocal解决,就可以不用管理锁的问题。创建了一个ThreadLocal全局对象,而它的每个属性(如local_school.student)就是线程的局部变量,可以任意读写而互不干扰
(3)多线程和多进程:
多线程 | 多进程 | |
稳定性 | 低(任何一个线程挂掉都直接造成整个进程崩溃) | 高(子进程崩溃不影响主进程或其他子进程) |
代价 | 低 | 高 |
效率 | 高 | 低 |
分部式 | 只能分布到同一台机器的多个CPU上 | 可以分布到多台机器上 |