Python技术进阶 | 如何正确使用进程和线程?
off999 2024-10-19 07:20 16 浏览 0 评论
为了提高程序的运行效率,Python与其他语言一样,提供了多进程和多线程的开发方式,这篇文章我们来讲Python的多进程和多线程开发。
进程
Python提供了mutilprocessing模块,为多进程编程提供了友好的API,并且提供了多进程之间信息同步和通信的相关组件,如Queue、Event、Pool、Lock、Pipe、Semaphore、Condition等模块。
函数当做进程
Python中创建多进程的方式有2种:
- 函数当做进程
- 类当做进程
逻辑简单的任务一般使用函数当做进程,逻辑较多或代码结构复杂的建议使用类当做进程。
首先来看函数当做进程的例子:
# coding: utf8
import os
import time
import random
from multiprocessing import Process
def task(name):
s = random.randint(1, 10)
print 'pid: %s, name: %s, sleep %s ...' % (os.getpid(), name, s)
time.sleep(s)
if __name__ == '__main__':
# 创建5个子进程执行
ps = []
for i in range(5):
p = Process(target=task, args=('p%s' % i, ))
ps.append(p)
p.start()
# 主进程等待子进程结束
for p in ps:
p.join()
# Output:
# pid: 52361, name: p0, sleep 8 ...
# pid: 52362, name: p1, sleep 7 ...
# pid: 52363, name: p2, sleep 8 ...
# pid: 52364, name: p3, sleep 3 ...
# pid: 52365, name: p4, sleep 2 ...
使用p = Process(target=func, args=(arg1, arg2...))即可创建一个进程,调用p.start()启动一个进程,p.join()使得主进程等待子进程执行结束后才退出。
当这个程序执行时,你可以ps查看一下进程,会发现一共有6个进程在执行,其中包括1个主进程,5个子进程。
类当做进程
# coding: utf8
import os
import random
import time
from multiprocessing import Process
class P(Process):
def run(self):
s = random.randint(1, 10)
print 'pid: %s, name: %s, sleep %s...' % (os.getpid(), self.name, s)
time.sleep(s)
if __name__ == '__main__':
# 创建5个进程并执行
ps = []
for i in range(5):
p = P()
ps.append(p)
p.start()
# 主进程等待子进程执行结束后退出
for p in ps:
p.join()
# Output:
# pid: 59138, name: P-2, sleep 5...
# pid: 59137, name: P-1, sleep 8...
# pid: 59139, name: P-3, sleep 8...
# pid: 59140, name: P-4, sleep 3...
# pid: 59141, name: P-5, sleep 6...
类P继承了Process,并重写了run方法,在调用start方法时会自动执行run方法,执行效果与上面类似。
Queue
如果多个进程之间需要通信,可以使用队列,Python提供了Queue模块,例子如下:
# coding: utf8
import time
import random
from multiprocessing import Process, Queue
class P1(Process):
def __init__(self, queue):
self.queue = queue
super(P1, self).__init__()
def run(self):
# 此进程负责put数据
print 'P1 put ...'
for i in range(5):
time.sleep(random.randint(1, 3))
self.queue.put(i)
print 'put: P1 -> %s' % i
class P2(Process):
def __init__(self, queue):
self.queue = queue
super(P2, self).__init__()
def run(self):
# 此进程负责read数据
print 'P2 read ...'
while 1:
i = self.queue.get()
print 'get: P2 -> %s' % i
if __name__ == '__main__':
# 创建多进程队列 使之可通信
queue = Queue()
# 创建进程
p1 = P1(queue)
p2 = P2(queue)
# 启动进程
p1.start()
p2.start()
# 主进程等待P1子进程执行
p1.join()
# P2执行的是死循环 只能强制结束
p2.terminate()
# Output:
# P1 put ...
# P2 read ...
# put: P1 -> 0
# get: P2 -> 0
# put: P1 -> 1
# get: P2 -> 1
# put: P1 -> 2
# get: P2 -> 2
# put: P1 -> 3
# get: P2 -> 3
# put: P1 -> 4
# get: P2 -> 4
一共2个进程,一个进程使用queue.put()负责向队列写入数据,另一个进程使用queue.get()队列中读取数据,实现了2个进程之间的信息通信。
Pipe
上面提到队列的使用场景常用于一端写入数据,另一端读取数据进行操作。
如果进程两端在读取数据时同时也想写入数据要怎么做?
Python多进程模块中提供了Pipe,意为管道的意思,两端都可以进行读写操作。
# coding: utf8
import time
import random
from multiprocessing import Process, Pipe
class P1(Process):
def __init__(self, pipe):
self.pipe = pipe
super(P1, self).__init__()
def run(self):
# send
print 'P1 send ...'
for i in range(3):
time.sleep(random.randint(1, 2))
self.pipe.send(i)
print 'send: P1 -> %s' % i
# recv
print 'P1 recv ...'
for i in range(3):
i = self.pipe.recv()
print 'recv: P1 -> %s' % i
class P2(Process):
def __init__(self, pipe):
self.pipe = pipe
super(P2, self).__init__()
def run(self):
# recv
print 'P2 recv ...'
for i in range(3):
i = self.pipe.recv()
print 'recv: P2 -> %s' % i
# send
print 'P2 send ...'
for i in range(3):
time.sleep(random.randint(1, 2))
self.pipe.send(i)
print 'send: P2 -> %s' % i
if __name__ == '__main__':
# 创建Pipe
pipe1, pipe2 = Pipe()
p1 = P1(pipe1)
p2 = P2(pipe2)
p1.start()
p2.start()
p1.join()
p2.join()
# Output:
# P1 send ...
# P2 recv ...
# send: P1 -> 0
# recv: P2 -> 0
# send: P1 -> 1
# recv: P2 -> 1
# send: P1 -> 2
# P1 recv ...
# recv: P2 -> 2
# P2 send ...
# send: P2 -> 0
# recv: P1 -> 0
# send: P2 -> 1
# recv: P1 -> 1
# send: P2 -> 2
# recv: P1 -> 2
创建一个Pipe会返回2个管道,这2个管道分别交给2个进程,即可实现这2个进程之间的互相通信。
Event
如果需要在多进程之间控制某些事件的开始与停止,也就是在多进程进程保持同步信号信息,可使用Event:
# coding: utf8
import time
import random
from multiprocessing import Process, Queue, Event
class P1(Process):
def __init__(self, queue, event):
self.queue = queue
self.event = event
super(P1, self).__init__()
def run(self):
# 阻塞 等待主进程信号
self.event.wait()
print 'P1 put ...'
for i in range(5):
time.sleep(random.randint(1, 3))
self.queue.put(i)
print 'put: P1 -> %s' % i
class P2(Process):
def __init__(self, queue, event):
self.queue = queue
self.event = event
super(P2, self).__init__()
def run(self):
# 阻塞 等待主进程信号
self.event.wait()
print 'P2 read ...'
while 1:
i = self.queue.get()
print 'get: P2 -> %s' % i
if __name__ == '__main__':
# 队列
queue = Queue()
# 事件
event = Event()
p1 = P1(queue, event)
p2 = P2(queue, event)
p1.start()
p2.start()
# 主进程让子进程阻塞3秒
print 'sleep 3s ...'
time.sleep(3)
# 向子进程发送信号 子进程向下执行
event.set()
p1.join()
p2.terminate()
# Output:
# sleep 3s...
# P1 put ...
# P2 read ...
# put: P1 -> 0
# get: P2 -> 0
# put: P1 -> 1
# get: P2 -> 1
# put: P1 -> 2
# get: P2 -> 2
# put: P1 -> 3
# get: P2 -> 3
# put: P1 -> 4
# get: P2 -> 4
执行程序后,我们发现2个子进程在执行到event.wait()时,阻塞在此,直到主进程休眠3秒后执行event.set()时,子进程才得以向下执行。
使用Event可以控制进程之间的同步问题。
Pool
多进程虽然可以提高运行效率,但同时也不建议无限制的创建进程,过多的进程会给操作系统的调度和上下文切换带来更大的负担,进程越来越多也有可能导致效率下降。
在multiiprocessing模块中,提供了进程池模块Pool,理论来说同时执行的进程数与CPU核心相等,才会保证最高效的运行效率。
# coding: utf8
import os
import random
import time
from multiprocessing import Pool
def task(name):
s = random.randint(1, 10)
print 'pid: %s, name: %s, sleep %s ...' % (os.getpid(), name, s)
time.sleep(s)
if __name__ == '__main__':
# 大小为5的进程池 同一时刻最多只有5个进程执行
pool = Pool(5)
# 运行10个任务
for i in range(10):
pool.apply_async(task, ('p-%s' % i, ))
# 必须先close才能join 表示不再添加新的进程
pool.close()
pool.join()
# Output:
# pid: 67193, name: p-0, sleep 3 ...
# pid: 67194, name: p-1, sleep 5 ...
# pid: 67195, name: p-2, sleep 5 ...
# pid: 67196, name: p-3, sleep 6 ...
# pid: 67197, name: p-4, sleep 9 ...
# pid: 67193, name: p-5, sleep 6 ...
# pid: 67194, name: p-6, sleep 5 ...
# pid: 67195, name: p-7, sleep 4 ...
# pid: 67196, name: p-8, sleep 3 ...
# pid: 67197, name: p-9, sleep 7 ...
上面代码定义了大小为5的进程池,也就是说不管向进程池里放入多少个任务,同一时刻只有5个进程在执行。
我们在编写多进程程序时,一般使用进程池的方式执行多个任务,保证高效的同时也避免资源的浪费
Lock
在执行多进程任务执行过程中,如果需要对同一资源(例如文件)进行访问时,为了防止一个进程操作的资源不被另一个进程篡改,可以使用Lock对其进行加锁互斥。
# coding: utf8
from multiprocessing import Process, Lock
class P1(Process):
def __init__(self, lock, fp):
self.lock = lock
self.fp = fp
super(P1, self).__init__()
def run(self):
# 只有一个进程能进入操作
with self.lock:
for i in range(5):
f = open(self.fp, 'a+')
f.write('p1 - %s\n' % i)
f.close()
class P2(Process):
def __init__(self, lock, fp):
self.lock = lock
self.fp = fp
super(P2, self).__init__()
def run(self):
# 只有一个进程能进入操作
with self.lock:
for i in range(5):
f = open(self.fp, 'a+')
f.write('p2 - %s\n' % i)
f.close()
if __name__ == '__main__':
# 进程锁
lock = Lock()
fp = 'test.txt'
p1 = P1(lock, fp)
p2 = P2(lock, fp)
p1.start()
p2.start()
p1.join()
p2.join()
上面代码对同一个文件进行操作时,如果不加锁,2个进程会同时向文件写入内容。如果想保证写入顺序,在写文件之前使用Lock加锁,就能保证只有一个进程能进入操作文件。
Semaphore
如果有一种场景,需要多个进程同时执行一些任务或访问某个资源,但要限制最大参与的进程数量,那么就可以使用Semaphore信号量来控制。
# coding: utf8
import time
import os
from multiprocessing import Process, Semaphore
# 最大4个进程同时操作
semaphore = Semaphore(4)
def task(name):
if semaphore.acquire():
print 'pid: %s, name: %s, sleep 1 ...' % (os.getpid(), name)
time.sleep(1)
semaphore.release()
if __name__ == '__main__':
ps = []
for i in range(10):
p = Process(target=task, args=('p%s' % i, ))
ps.append(p)
p.start()
for p in ps:
p.join()
# Output:
# pid: 37147, name: p0, sleep 1 ...
# pid: 37148, name: p1, sleep 1 ...
# pid: 37149, name: p2, sleep 1 ...
# pid: 37150, name: p3, sleep 1 ...
# pid: 37151, name: p4, sleep 1 ...
# pid: 37152, name: p5, sleep 1 ...
# pid: 37153, name: p6, sleep 1 ...
# pid: 37154, name: p7, sleep 1 ...
# pid: 37155, name: p8, sleep 1 ...
# pid: 37156, name: p9, sleep 1 ...
执行上面的代码,你会发现虽然创建了10个进程,但同一时刻只有4个进程能能够执行真正的逻辑。
Condition
如果你有使用Lock + Event结合的场景,可以使用Condition,它基本上包含了这2种特性,在加锁的同时,还可以根据逻辑条件让其他进程等待或重新唤醒。
# coding: utf8
import time
import random
from multiprocessing import Process, Queue, Condition
def produer(queue, condition):
while 1:
# 获取锁
if condition.acquire():
if not queue.empty():
# 等待其他进程唤醒
condition.wait()
i = random.randint(1, 10)
queue.put(i)
print 'produer --> %s' % i
# 唤醒其他进程
condition.notify()
# 释放锁
condition.release()
time.sleep(1)
def consumer(queue, condition):
while 1:
# 获取锁
if condition.acquire():
if queue.empty():
# 等待其他进程唤醒
condition.wait()
i = queue.get()
print 'consumer --> %s' % i
# 唤醒其他进程
condition.notify()
# 释放锁
condition.release()
time.sleep(1)
if __name__ == '__main__':
queue = Queue()
condition = Condition()
p1 = Process(target=produer, args=(queue, condition))
p2 = Process(target=consumer, args=(queue, condition))
p1.start()
p2.start()
p1.join()
p2.join()
# Output:
# produer --> 10
# consumer --> 10
# produer --> 4
# consumer --> 4
# produer --> 5
# consumer --> 5
# ...
Condition是一种更高级的控制进程同步和资源控制的方式。
线程
线程是进程执行的最小单位,比进程更轻量,一个进程至少包含一个线程,一个进程中的所有线程共享这个进程的地址空间和资源句柄。
在Python代码执行中,默认是单进程单线程执行的。
如果想要编写多线程程序,Python也提供了threading模块,同时也提供了线程之间信息同步和信号控制的组件。
函数当做线程
创建线程与创建进程类似,也有2种方式:
- 函数当做线程
- 类当做线程
函数当做线程的例子如下:
# coding: utf8
import threading
def run(name):
for i in range(3):
print '%s --> %s' % (name, i)
if __name__ == '__main__':
# 创建2个线程
t1 = threading.Thread(target=run, args=('t1', ))
t2 = threading.Thread(target=run, args=('t2', ))
# 开始执行
t1.start()
t2.start()
# 主线程等待其他线程结束
t1.join()
t2.join()
# Output:
# t1 --> 0
# t2 --> 0
# t2 --> 1
# t2 --> 2
# t1 --> 1
# t1 --> 2
与进程很类似,t = threading.Thread(target=func, args=(arg1, arg2...))创建一个线程,t.start()开始执行线程,t.join()使主线程等待其他线程执行结束。
类当做线程
# coding: utf8
import threading
class A(threading.Thread):
def run(self):
for i in range(5):
print self.name, i
if __name__ == '__main__':
a1 = A()
a2 = A()
# 执行线程
a1.start()
a2.start()
# 主线程等待其他线程结束
a1.join()
a2.join()
只要继承threading.Thread类,重写run方法,这个类就会以多线程的方式执行run方法里的逻辑。
Queue
多线程之间也可以使用队列进行数据传输:
# coding: utf8
import time
import random
from Queue import Queue
from threading import Thread
class T1(Thread):
def __init__(self, queue):
self.queue = queue
super(T1, self).__init__()
def run(self):
print 'T1 put ...'
for i in range(5):
time.sleep(random.randint(1, 3))
self.queue.put(i)
print 'put: T1 -> %s' % i
class T2(Thread):
def __init__(self, queue):
self.queue = queue
self._running = True
super(T2, self).__init__()
def stop(self):
self._running = False
def run(self):
print 'T2 read ...'
while self._running:
i = self.queue.get()
print 'get: T2 -> %s' % i
if __name__ == '__main__':
# 创建多线程队列
queue = Queue()
# 创建进程
t1 = T1(queue)
t2 = T2(queue)
# 启动进程
t1.start()
t2.start()
# T2线程10秒后停止
time.sleep(10)
t2.stop()
# 主进程等待线程执行
t1.join()
t2.join()
# Output:
# T1 put ...
# T2 read ...
# put: T1 -> 0
# get: T2 -> 0
# put: T1 -> 1
# get: T2 -> 1
# put: T1 -> 2
# get: T2 -> 2
# put: T1 -> 3
# get: T2 -> 3
# put: T1 -> 4
# get: T2 -> 4
Event
多线程的同步也有Event可以控制:
# coding: utf8
import time
import random
from Queue import Queue
from threading import Thread, Event
class T1(Thread):
def __init__(self, queue, event):
self.queue = queue
self.event = event
super(T1, self).__init__()
def run(self):
# 阻塞 等待主线程信号
self.event.wait()
print 'T1 put ...'
for i in range(5):
time.sleep(random.randint(1, 3))
self.queue.put(i)
print 'put: T1 -> %s' % i
class T2(Thread):
def __init__(self, queue, event):
self.queue = queue
self.event = event
self._running = True
super(T2, self).__init__()
def stop(self):
self._running = False
def run(self):
# 阻塞 等待主线程信号
self.event.wait()
print 'T2 read ...'
while self._running:
i = self.queue.get()
print 'get: T2 -> %s' % i
if __name__ == '__main__':
# 队列
queue = Queue()
# 多线程事件
event = Event()
t1 = T1(queue, event)
t2 = T2(queue, event)
t1.start()
t2.start()
# 主线程让其他线程阻塞3秒
print 'sleep 3s...'
time.sleep(3)
event.set()
# T2线程10秒后停止
time.sleep(10)
t2.stop()
t1.join()
t2.join()
# Output:
# sleep 3s...
# T1 put ...
# T2 read ...
# put: T1 -> 0
# get: T2 -> 0
# put: T1 -> 1
# get: T2 -> 1
# put: T1 -> 2
# get: T2 -> 2
# put: T1 -> 3
# get: T2 -> 3
# put: T1 -> 4
Pool
避免无限制的创建线程,使用线程池执行任务:
# coding: utf8
import time
import random
from multiprocessing.pool import ThreadPool
def task(name):
s = random.randint(1, 10)
print 'name: %s, sleep %s ...' % (name, s)
time.sleep(s)
if __name__ == '__main__':
# 大小为5的线程池
pool = ThreadPool(5)
# 运行10个任务
for i in range(10):
pool.apply_async(task, ('t-%s' % i, ))
# 必须先close才能join 表示不再添加新的线程
pool.close()
pool.join()
# Output:
# name: t-0, sleep 1 ...
# name: t-1, sleep 4 ...
# name: t-2, sleep 4 ...
# name: t-3, sleep 10 ...
# name: t-4, sleep 9 ...
# name: t-5, sleep 8 ...
# name: t-6, sleep 2 ...
# name: t-7, sleep 2 ...
# name: t-8, sleep 4 ...
# name: t-9, sleep 6 ...
Semaphore
允许多个线程同时操作某个资源并限制最大线程数,使用Semaphore:
# coding: utf8
import time
import os
from threading import Thread, Semaphore
# 最大4个线程同时操作
semaphore = Semaphore(4)
def task(name):
if semaphore.acquire():
print 'name: %s, sleep 1 ...' % name
time.sleep(1)
semaphore.release()
if __name__ == '__main__':
ts = []
for i in range(10):
t = Thread(target=task, args=('t%s' % i, ))
ts.append(t)
t.start()
for t in ts:
t.join()
# Output:
# name: t0, sleep 1 ...
# name: t2, sleep 1 ...
# name: t1, sleep 1 ...
# name: t3, sleep 1 ...
# name: t4, sleep 1 ...
# name: t5, sleep 1 ...
# name: t7, sleep 1 ...
# name: t6, sleep 1 ...
# name: t8, sleep 1 ...
# name: t9, sleep 1 ...
Condition
与多进程类似,Condition是Lock + Event的结合:
# coding: utf8
import time
import random
from Queue import Queue
from threading import Thread, Condition
def produer(queue, condition):
for i in range(5):
# 获取锁
if condition.acquire():
if not queue.empty():
# 等待其他线程唤醒
condition.wait()
i = random.randint(1, 10)
queue.put(i)
print 'produer --> %s' % i
# 唤醒其他线程
condition.notify()
# 释放锁
condition.release()
time.sleep(1)
def consumer(queue, condition):
for i in range(5):
# 获取锁
if condition.acquire():
if queue.empty():
# 等待其他线程唤醒
condition.wait()
i = queue.get()
print 'consumer --> %s' % i
# 唤醒其他线程
condition.notify()
# 释放锁
condition.release()
time.sleep(1)
if __name__ == '__main__':
queue = Queue()
condition = Condition()
t1 = Thread(target=produer, args=(queue, condition))
t2 = Thread(target=consumer, args=(queue, condition))
t1.start()
t2.start()
t1.join()
t2.join()
# Output:
# produer --> 3
# consumer --> 3
# produer --> 2
# consumer --> 2
# produer --> 2
# consumer --> 2
# produer --> 7
# consumer --> 7
# produer --> 5
# consumer --> 5
concurrent模块
上面介绍了很多进程、线程各种常用的开发方式,其实最常用的编程模式还是使用进程池或线程池来执行进程、线程。
这里有必要推荐一下concurrent模块,这个模块非常友好的封装了进程和线程最常用的操作,使用起来更简单易用。
并且在Python3.2以后,已经是纳入官方标准模块。
Python3.2以下需要手动安装此模块:
pip install futures
多进程
# coding: utf8
from concurrent.futures import ProcessPoolExecutor
def task(total):
"""模拟CPU密集运算"""
num = 0
for i in range(total):
num += i
return num
if __name__ == '__main__':
# 进程池
pool = ProcessPoolExecutor(max_workers=5)
# 批量任务 放入进程池执行
result = pool.map(task, [100, 1000, 10000, 100000])
# 输出结果
for item in result:
print item
使用ProcessPoolExecutor创建进程池,调用pool.map方法批量加入任务并执行,然后输出每个进程的执行结果。
也可以使用submit提交单个任务在进程池中执行:
# coding: utf8
from concurrent.futures import ProcessPoolExecutor
def task(total):
"""模拟CPU密集任务"""
num = 0
for i in range(total):
num += i
return num
if __name__ == '__main__':
# 进程池
pool = ProcessPoolExecutor(max_workers=5)
# 使用submit提交任务
results = []
results.append(pool.submit(task, 100))
results.append(pool.submit(task, 1000))
results.append(pool.submit(task, 10000))
results.append(pool.submit(task, 10000))
# 输出结果
for future in results:
print future.result()
注意,pool.submit提交后返回的是Future对象,它意味着在未来的某个时刻才会得到结果,所以在输出结果时,需要调用future.result()方法拿到真正的执行结果。
多线程
线程池的方式与进程池类似,只需把ProcessPoolExecutor换成ThreadPoolExecutor即可:
# coding: utf8
import requests
from concurrent.futures import ThreadPoolExecutor
def task(url):
"""模拟IO密集任务"""
return requests.get(url).status_code
if __name__ == '__main__':
# 线程池
pool = ThreadPoolExecutor(max_workers=5)
# 批量任务 放入线程池执行
urls = ['http://www.baidu.com', 'http://www.163.com', 'http://www.taobao.com']
result = pool.map(task, urls)
# 输出结果
for item in result:
print item
# coding: utf8
import requests
from concurrent.futures import ThreadPoolExecutor
def task(url):
"""模拟IO密集运算"""
return requests.get(url).status_code
if __name__ == '__main__':
# 线程池
pool = ThreadPoolExecutor(max_workers=5)
# 使用submit 提交任务到线程池
results = []
results.append(pool.submit(task, 'http://www.baidu.com'))
results.append(pool.submit(task, 'http://www.163.com'))
results.append(pool.submit(task, 'http://www.taobao.com'))
# 输出结果
for future in results:
print future.result()
相关推荐
- python入门到脱坑经典案例—清空列表
-
在Python中,清空列表是一个基础但重要的操作。clear()方法是最直接的方式,但还有其他方法也可以实现相同效果。以下是详细说明:1.使用clear()方法(Python3.3+推荐)...
- python中元组,列表,字典,集合删除项目方式的归纳
-
九三,君子终日乾乾,夕惕若,厉无咎。在使用python过程中会经常遇到这四种集合数据类型,今天就对这四种集合数据类型中删除项目的操作做个总结性的归纳。列表(List)是一种有序和可更改的集合。允许重复...
- Linux 下海量文件删除方法效率对比,最慢的竟然是 rm
-
Linux下海量文件删除方法效率对比,本次参赛选手一共6位,分别是:rm、find、findwithdelete、rsync、Python、Perl.首先建立50万个文件$testfor...
- 数据结构与算法——链式存储(链表)的插入及删除,
-
持续分享嵌入式技术,操作系统,算法,c语言/python等,欢迎小友关注支持上篇文章我们讲述了链表的基本概念及一些查找遍历的方法,本篇我们主要将一下链表的插入删除操作,以及采用堆栈方式如何创建链表。链...
- Python自动化:openpyxl写入数据,插入删除行列等基础操作
-
importopenpyxlwb=openpyxl.load_workbook("example1.xlsx")sh=wb['Sheet1']写入数据#...
- 在Linux下软件的安装与卸载(linux里的程序的安装与卸载命令)
-
通过apt安装/协助软件apt是AdvancedPackagingTool,是Linux下的一款安装包管理工具可以在终端中方便的安装/卸载/更新软件包命令使用格式:安装软件:sudoapt...
- Python 批量卸载关联包 pip-autoremove
-
pip工具在安装扩展包的时候会自动安装依赖的关联包,但是卸载时只删除单个包,无法卸载关联的包。pip-autoremove就是为了解决卸载关联包的问题。安装方法通过下面的命令安装:pipinsta...
- 用Python在Word文档中插入和删除文本框
-
在当今自动化办公需求日益增长的背景下,通过编程手段动态管理Word文档中的文本框元素已成为提升工作效率的关键技术路径。文本框作为文档排版中灵活的内容容器,既能承载多模态信息(如文字、图像),又可实现独...
- Python 从列表中删除值的多种实用方法详解
-
#Python从列表中删除值的多种实用方法详解在Python编程中,列表(List)是一种常用的数据结构,具有动态可变的特性。当我们需要从列表中删除元素时,根据不同的场景(如按值删除、按索引删除、...
- Python 中的前缀删除操作全指南(python删除前导0)
-
1.字符串前缀删除1.1使用内置方法Python提供了几种内置方法来处理字符串前缀的删除:#1.使用removeprefix()方法(Python3.9+)text="...
- 每天学点Python知识:如何删除空白
-
在Python中,删除空白可以分为几种不同的情况,常见的是针对字符串或列表中空白字符的处理。一、删除字符串中的空白1.删除字符串两端的空白(空格、\t、\n等)使用.strip()方法:s...
- Linux系统自带Python2&yum的卸载及重装
-
写在前面事情的起因是我昨天在测试Linux安装Python3的shell脚本时,需要卸载Python3重新安装一遍。但是通过如下命令卸载python3时,少写了个3,不小心将系统自带的python2也...
- 如何使用Python将多个excel文件数据快速汇总?
-
在数据分析和处理的过程中,Excel文件是我们经常会遇到的数据格式之一。本文将通过一个具体的示例,展示如何使用Python和Pandas库来读取、合并和处理多个Excel文件的数据,并最终生成一个包含...
- 【第三弹】用Python实现Excel的vlookup功能
-
今天继续用pandas实现Excel的vlookup功能,假设我们的2个表长成这样:我们希望把Sheet2的部门匹在Sheet1的最后一列。话不多说,先上代码:importpandasaspd...
- python中pandas读取excel单列及连续多列数据
-
案例:想获取test.xls中C列、H列以后(当H列后列数未知时)的所有数据。importpandasaspdfile_name=r'D:\test.xls'#表格绝对...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python自定义函数 (53)
- python进度条 (67)
- python吧 (67)
- python字典遍历 (54)
- python的for循环 (65)
- python格式化字符串 (61)
- python串口编程 (60)
- python读取文件夹下所有文件 (59)
- java调用python脚本 (56)
- python操作mysql数据库 (66)
- python字典增加键值对 (53)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python人脸识别 (54)
- python多态 (60)
- python命令行参数 (53)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)