python對(duì)RabbitMQ的簡(jiǎn)單入門(mén)使用教程
(一)RabbitMQ的簡(jiǎn)介
RabbitMq 是實(shí)現(xiàn)了高級(jí)消息隊(duì)列協(xié)議(AMQP)的開(kāi)源消息代理中間件。消息隊(duì)列是一種應(yīng)用程序?qū)?yīng)用程序的通行方式,應(yīng)用程序通過(guò)寫(xiě)消息,將消息傳遞于隊(duì)列,由另一應(yīng)用程序讀取 完成通信。而作為中間件的 RabbitMq 無(wú)疑是目前最流行的消息隊(duì)列之一。目前使用較多的消息隊(duì)列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ。
RabbitMQ總體架構(gòu)

PS:生產(chǎn)者和消費(fèi)者可能在不同的程序或主機(jī)中,當(dāng)然也有可能一個(gè)程序有可能既是生產(chǎn)者,也是消費(fèi)者。
RabbitMq 應(yīng)用場(chǎng)景廣泛:
1.系統(tǒng)的高可用:日常生活當(dāng)中各種商城秒殺,高流量,高并發(fā)的場(chǎng)景。當(dāng)服務(wù)器接收到如此大量請(qǐng)求處理業(yè)務(wù)時(shí),有宕機(jī)的風(fēng)險(xiǎn)。某些業(yè)務(wù)可能極其復(fù)雜,但這部分不是高時(shí)效性,不需要立即反饋給用戶(hù),我們可以將這部分處理請(qǐng)求拋給隊(duì)列,讓程序后置去處理,減輕服務(wù)器在高并發(fā)場(chǎng)景下的壓力。
2.分布式系統(tǒng),集成系統(tǒng),子系統(tǒng)之間的對(duì)接,以及架構(gòu)設(shè)計(jì)中常常需要考慮消息隊(duì)列的應(yīng)用。
(二)RabbitMQ的安裝
apt-get update apt-get install erlang apt-get install rabbitmq-server #啟動(dòng)rabbitmq: service rabbitmq-server start #停止rabbitmq: service rabbitmq-server stop #重啟rabbitmq: service rabbitmq-server restart #啟動(dòng)rabbitmq插件:rabbitmq-plugins enable rabbitmq_management
啟用rabbitmq_management插件后就可以登錄后臺(tái)管理頁(yè)面了,瀏覽器輸入ip:15672

自帶的密碼和用戶(hù)名都是guest,但是只能本機(jī)登錄
所以下面我們添加新用戶(hù),和自定義權(quán)限
#添加新用戶(hù) rabbitmqctl add_user 用戶(hù)名 密碼 #給指定用戶(hù)添加管理員權(quán)限 rabbitmqctl set_user_tags 用戶(hù)名 administrator 給用戶(hù)添加權(quán)限 rabbitmqctl set_permissions -p / 用戶(hù)名 ".*" ".*" ".*"
在web頁(yè)面輸入用戶(hù)名,和密碼

(三)python操作RabbitMQ
python中使用pika操作RabbitMQ
pip install pika #皮卡皮卡,哈哈
(四)RabbitMQ簡(jiǎn)單模式

上代碼
# coding=utf-8
### 生產(chǎn)者
import pika
import time
user_info = pika.PlainCredentials('root', 'root')#用戶(hù)名和密碼
connection = pika.BlockingConnection(pika.ConnectionParameters('ip', 5672, '/', user_info))#連接服務(wù)器上的RabbitMQ服務(wù)
# 創(chuàng)建一個(gè)channel
channel = connection.channel()
# 如果指定的queue不存在,則會(huì)創(chuàng)建一個(gè)queue,如果已經(jīng)存在 則不會(huì)做其他動(dòng)作,官方推薦,每次使用時(shí)都可以加上這句
channel.queue_declare(queue='hello')
for i in range(0, 100):
channel.basic_publish(exchange='',#當(dāng)前是一個(gè)簡(jiǎn)單模式,所以這里設(shè)置為空字符串就可以了
routing_key='hello',# 指定消息要發(fā)送到哪個(gè)queue
body='{}'.format(i)# 指定要發(fā)送的消息
)
time.sleep(1)
# 關(guān)閉連接
# connection.close()PS:RabbitMQ中所有的消息都要先通過(guò)交換機(jī),空字符串表示使用默認(rèn)的交換機(jī)
# coding=utf-8
### 消費(fèi)者
import pika
user_info = pika.PlainCredentials('root', 'root')
connection = pika.BlockingConnection(pika.ConnectionParameters('ip', 5672, '/', user_info))
channel = connection.channel()
# 如果指定的queue不存在,則會(huì)創(chuàng)建一個(gè)queue,如果已經(jīng)存在 則不會(huì)做其他動(dòng)作,生產(chǎn)者和消費(fèi)者都做這一步的好處是
# 這樣生產(chǎn)者和消費(fèi)者就沒(méi)有必要的先后啟動(dòng)順序了
channel.queue_declare(queue='hello')
# 回調(diào)函數(shù)
def callback(ch, method, properties, body):
print('消費(fèi)者收到:{}'.format(body))
# channel: 包含channel的一切屬性和方法
# method: 包含 consumer_tag, delivery_tag, exchange, redelivered, routing_key
# properties: basic_publish 通過(guò) properties 傳入的參數(shù)
# body: basic_publish發(fā)送的消息
channel.basic_consume(queue='hello', # 接收指定queue的消息
auto_ack=True, # 指定為T(mén)rue,表示消息接收到后自動(dòng)給消息發(fā)送方回復(fù)確認(rèn),已收到消息
on_message_callback=callback # 設(shè)置收到消息的回調(diào)函數(shù)
)
print('Waiting for messages. To exit press CTRL+C')
# 一直處于等待接收消息的狀態(tài),如果沒(méi)收到消息就一直處于阻塞狀態(tài),收到消息就調(diào)用上面的回調(diào)函數(shù)
channel.start_consuming()
對(duì)于上面的這種模式,有一下兩個(gè)不好的地方:
一個(gè)是在我們的消費(fèi)者還沒(méi)開(kāi)始消費(fèi)完隊(duì)列里的消息,如果這時(shí)rabbitmq服務(wù)掛了,那么消息隊(duì)列里的消息將會(huì)全部丟失,解決方法是在聲明隊(duì)列時(shí),聲明隊(duì)列為可持久化存儲(chǔ)隊(duì)列,并且在生產(chǎn)者在將消息插入到消息隊(duì)列時(shí),設(shè)置消息持久化存儲(chǔ),具體如下
# coding=utf-8
### 生產(chǎn)者
import pika
import time
user_info = pika.PlainCredentials('root', 'root')
connection = pika.BlockingConnection(pika.ConnectionParameters('ip', 5672, '/', user_info))
# 創(chuàng)建一個(gè)channel
channel = connection.channel()
# 如果指定的queue不存在,則會(huì)創(chuàng)建一個(gè)queue,如果已經(jīng)存在 則不會(huì)做其他動(dòng)作,官方推薦,每次使用時(shí)都可以加上這句
channel.queue_declare(queue='durable_queue',durable=True)
#PS:這里不同種隊(duì)列不允許名字相同
for i in range(0, 100):
channel.basic_publish(exchange='',
routing_key='durable_queue',
body='{}'.format(i),
properties=pika.BasicProperties(delivery_mode=2)
)
# 關(guān)閉連接
# connection.close()消費(fèi)者與上面的消費(fèi)者沒(méi)有什么不同,具體的就是消費(fèi)聲明的隊(duì)列,也要是可持久化的隊(duì)列,還有就是,即使在生產(chǎn)者插入消息時(shí),設(shè)置當(dāng)前消息持久化存儲(chǔ)(properties=pika.BasicProperties(delivery_mode=2)),并不能百分百保證消息真的被持久化,因?yàn)镽abbitMQ掛掉的時(shí)候它可能還保存在緩存中,沒(méi)來(lái)得及同步到磁盤(pán)中
在生產(chǎn)者插入消息后,立刻停止rabbitmq,并重新啟動(dòng),其實(shí)我們?cè)趙eb管理頁(yè)面也可看到未被消費(fèi)的信息,當(dāng)然在啟動(dòng)消費(fèi)者后也成功接收到了消息

上面說(shuō)的第二點(diǎn)不好就是,如果在消費(fèi)者獲取到隊(duì)列里的消息后,在回調(diào)函數(shù)的處理過(guò)程中,消費(fèi)者突然出錯(cuò)或程序崩潰等異常,那么就會(huì)造成這條消息并未被實(shí)際正常的處理掉。為了解決這個(gè)問(wèn)題,我們只需在消費(fèi)者basic_consume(auto_ack=False),并在回調(diào)函數(shù)中設(shè)置手動(dòng)應(yīng)答即可ch.basic_ack(delivery_tag=method.delivery_tag),具體如下
# coding=utf-8
### 消費(fèi)者
import pika
import time
user_info = pika.PlainCredentials('root', 'root')
connection = pika.BlockingConnection(pika.ConnectionParameters('ip', 5672, '/', user_info))
channel = connection.channel()
# 如果指定的queue不存在,則會(huì)創(chuàng)建一個(gè)queue,如果已經(jīng)存在 則不會(huì)做其他動(dòng)作,生產(chǎn)者和消費(fèi)者都做這一步的好處是
# 這樣生產(chǎn)者和消費(fèi)者就沒(méi)有必要的先后啟動(dòng)順序了
channel.queue_declare(queue='queue')
# 回調(diào)函數(shù)
def callback(ch, method, properties, body):
time.sleep(5)
ch.basic_ack(delivery_tag=method.delivery_tag)
print('消費(fèi)者收到:{}'.format(body.decode('utf-8')))
# channel: 包含channel的一切屬性和方法
# method: 包含 consumer_tag, delivery_tag, exchange, redelivered, routing_key
# properties: basic_publish 通過(guò) properties 傳入的參數(shù)
# body: basic_publish發(fā)送的消息
channel.basic_consume(queue='queue', # 接收指定queue的消息
auto_ack=False, # 指定為False,表示取消自動(dòng)應(yīng)答,交由回調(diào)函數(shù)手動(dòng)應(yīng)答
on_message_callback=callback # 設(shè)置收到消息的回調(diào)函數(shù)
)
# 應(yīng)答的本質(zhì)是告訴消息隊(duì)列可以將這條消息銷(xiāo)毀了
print('Waiting for messages. To exit press CTRL+C')
# 一直處于等待接收消息的狀態(tài),如果沒(méi)收到消息就一直處于阻塞狀態(tài),收到消息就調(diào)用上面的回調(diào)函數(shù)
channel.start_consuming()這里只需要配置消費(fèi)者,生產(chǎn)者并不要修改
還有就是在上的使用方式在,都是一個(gè)生產(chǎn)者和一個(gè)消費(fèi)者,還有一種情況就是,一個(gè)生產(chǎn)者和多個(gè)消費(fèi)者,即多個(gè)消費(fèi)者同時(shí)監(jiān)聽(tīng)一個(gè)消息隊(duì)列,這時(shí)候隊(duì)列里的消息就是輪詢(xún)分發(fā)(即如果消息隊(duì)列里有100條信息,如果有2個(gè)消費(fèi)者,那么每個(gè)就會(huì)收到50條信息),但是在某些情況下,不同的消費(fèi)者處理任務(wù)的能力是不同的,這時(shí)還按照輪詢(xún)的方式分發(fā)消息并不是很合理,那么只需要再配合手動(dòng)應(yīng)答的方式,設(shè)置消費(fèi)者接收的消息沒(méi)有處理完,隊(duì)列就不要給我放送新的消息即可,具體配置方式如下:
# coding=utf-8
### 消費(fèi)者
import pika
import time
user_info = pika.PlainCredentials('root', 'root')
connection = pika.BlockingConnection(pika.ConnectionParameters('ip', 5672, '/', user_info))
channel = connection.channel()
# 如果指定的queue不存在,則會(huì)創(chuàng)建一個(gè)queue,如果已經(jīng)存在 則不會(huì)做其他動(dòng)作,生產(chǎn)者和消費(fèi)者都做這一步的好處是
# 這樣生產(chǎn)者和消費(fèi)者就沒(méi)有必要的先后啟動(dòng)順序了
channel.queue_declare(queue='queue')
# 回調(diào)函數(shù)
def callback(ch, method, properties, body):
time.sleep(0)#通過(guò)設(shè)置休眠時(shí)間來(lái)模擬不同消費(fèi)者的處理時(shí)間
ch.basic_ack(delivery_tag=method.delivery_tag)
print('消費(fèi)者收到:{}'.format(body.decode('utf-8')))
# prefetch_count表示接收的消息數(shù)量,當(dāng)我接收的消息沒(méi)有處理完(用basic_ack標(biāo)記消息已處理完畢)之前不會(huì)再接收新的消息了
channel.basic_qos(prefetch_count=1) # 還有就是這個(gè)設(shè)置必須在basic_consume之上,否則不生效
channel.basic_consume(queue='queue', # 接收指定queue的消息
auto_ack=False, # 指定為False,表示取消自動(dòng)應(yīng)答,交由回調(diào)函數(shù)手動(dòng)應(yīng)答
on_message_callback=callback # 設(shè)置收到消息的回調(diào)函數(shù)
)
# 應(yīng)答的本質(zhì)是告訴消息隊(duì)列可以將這條消息銷(xiāo)毀了
print('Waiting for messages. To exit press CTRL+C')
# 一直處于等待接收消息的狀態(tài),如果沒(méi)收到消息就一直處于阻塞狀態(tài),收到消息就調(diào)用上面的回調(diào)函數(shù)
channel.start_consuming()PS:這種情況必須關(guān)閉自動(dòng)應(yīng)答ack,改成手動(dòng)應(yīng)答。使用basicQos(perfetch=1)限制每次只發(fā)送不超過(guò)1條消息到同一個(gè)消費(fèi)者,消費(fèi)者必須手動(dòng)反饋告知隊(duì)列,才會(huì)發(fā)送下一個(gè)
(五)RabbitMQ發(fā)布訂閱模式
發(fā)布訂閱會(huì)將消息發(fā)送給所有的訂閱者,而消息隊(duì)列中的數(shù)據(jù)被消費(fèi)一次便消失。所以,RabbitMQ實(shí)現(xiàn)發(fā)布和訂閱時(shí),會(huì)為每一個(gè)訂閱者創(chuàng)建一個(gè)隊(duì)列,而發(fā)布者發(fā)布消息時(shí),會(huì)將消息放置在所有相關(guān)隊(duì)列中

這個(gè)模式中會(huì)引入交換機(jī)的概念,其實(shí)在RabbitMQ中,所有的生產(chǎn)者都不會(huì)直接把消息發(fā)送到隊(duì)列中,甚至生產(chǎn)者都不知道消息在發(fā)出后有沒(méi)有發(fā)送到queue中,事實(shí)上,生產(chǎn)者只能將消息發(fā)送給交換機(jī),由交換機(jī)來(lái)決定發(fā)送到哪個(gè)隊(duì)列中。
交換機(jī)的一端用來(lái)從生產(chǎn)者中接收消息,另一端用來(lái)發(fā)送消息到隊(duì)列,交換機(jī)的類(lèi)型規(guī)定了怎么處理接收到的消息,發(fā)布訂閱模式使用到的交換機(jī)類(lèi)型為 fanout ,這種交換機(jī)類(lèi)型非常簡(jiǎn)單,就是將接收到的消息廣播給已知的(即綁定到此交換機(jī)的)所有消費(fèi)者。
當(dāng)然,如果不想使用特定的交換機(jī),可以使用 exchange=’’ 表示使用默認(rèn)的交換機(jī),默認(rèn)的交換機(jī)會(huì)將消息發(fā)送到 routing_key 指定的queue,可以參考簡(jiǎn)單模式。
上代碼:
#生產(chǎn)者
import pika
user_info = pika.PlainCredentials('root', 'root')
connection = pika.BlockingConnection(pika.ConnectionParameters('ip', 5672, '/', user_info))
channel = connection.channel()
# 創(chuàng)建一個(gè)指定名稱(chēng)的交換機(jī),并指定類(lèi)型為fanout,用于將接收到的消息廣播到所有queue中
channel.exchange_declare(exchange='交換機(jī)', exchange_type='fanout')
# 將消息發(fā)送給指定的交換機(jī),在fanout類(lèi)型中,routing_key=''表示不用發(fā)送到指定queue中,
# 而是將發(fā)送到綁定到此交換機(jī)的所有queue
channel.basic_publish(exchange='交換機(jī)', routing_key='', body='這是一條測(cè)試消息')
#消費(fèi)者
import pika
user_info = pika.PlainCredentials('root', 'root')
connection = pika.BlockingConnection(pika.ConnectionParameters('ip', 5672, '/', user_info))
channel = connection.channel()
channel.exchange_declare(exchange='交換機(jī)', exchange_type='fanout')
# 使用RabbitMQ給自己生成一個(gè)專(zhuān)有的queue
result = channel.queue_declare(queue='333')
# result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue
# 這里如果設(shè)置exclusive=True參數(shù),那么該隊(duì)列就是一個(gè)只有隊(duì)列,在消費(fèi)者結(jié)束后,該專(zhuān)有隊(duì)列也會(huì)自動(dòng)清除,如果queue=''沒(méi)有設(shè)置名字的話(huà),那么就會(huì)自動(dòng)生成一個(gè)
# 不會(huì)重復(fù)的隊(duì)列名
# 將queue綁定到指定交換機(jī)
channel.queue_bind(exchange='交換機(jī)', queue=queue_name)
print(' [*] Waiting for message.')
def callback(ch, method, properties, body):
print("消費(fèi)者收到:{}".format(body.decode('utf-8')))
channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)
channel.start_consuming()該模式與簡(jiǎn)單模式的還有一個(gè)區(qū)別就是,這里的消息隊(duì)列都是由消費(fèi)者聲明的,所以如果是生產(chǎn)者先啟動(dòng),并將消息發(fā)給交換機(jī)的畫(huà),這里的消息就會(huì)丟失,所以我們也可以在消費(fèi)者端聲明隊(duì)列并綁定交換機(jī)(不能是專(zhuān)有隊(duì)列),所以仔細(xì)想想,其實(shí)這所謂的發(fā)布訂閱模式并沒(méi)有說(shuō)什么了不起,它不過(guò)是讓交換機(jī)同時(shí)推送多條消息給綁定的隊(duì)列,我們當(dāng)然也可以在簡(jiǎn)單模式的基礎(chǔ)上多進(jìn)行幾次basic_publish發(fā)送消息到指定的隊(duì)列。當(dāng)然我們這樣做的話(huà),可能就沒(méi)辦法做到由交換機(jī)的同時(shí)發(fā)送了,效率可能也沒(méi)有一次basic_publish的高
(六)RabbitMQ RPC模式

下面實(shí)現(xiàn)由rpc遠(yuǎn)程調(diào)用加減運(yùn)算
客戶(hù)端
import pika
import uuid
import json
class RPC(object):
def __init__(self):
self.call_id = None
self.response = None
user_info = pika.PlainCredentials('root', 'root')
self.connection = pika.BlockingConnection(pika.ConnectionParameters('ip', 5672, '/', user_info))
self.channel = self.connection.channel()
# 創(chuàng)建一個(gè)此客戶(hù)端專(zhuān)用的queue,用于接收服務(wù)端發(fā)過(guò)來(lái)的消息
result = self.channel.queue_declare(queue='', exclusive=True)
self.callback_queue = result.method.queue
self.channel.basic_consume(
queue=self.callback_queue,
on_message_callback=self.on_response,
auto_ack=True)
def on_response(self, ch, method, props, body):
# 判斷接收到的response是否屬于對(duì)應(yīng)request
if self.call_id == props.correlation_id:
self.response = json.loads(body.decode('utf-8')).get('result')
def call(self, func, param):
self.response = None
self.call_id = str(uuid.uuid4()) # 為該消息指定uuid,類(lèi)似于請(qǐng)求id
self.channel.queue_declare(queue='rpc_queue')
self.channel.basic_publish(
exchange='',
routing_key='rpc_queue', # 將消息發(fā)送到該queue
properties=pika.BasicProperties(
reply_to=self.callback_queue, # 從該queue中取消息
correlation_id=self.call_id, # 為此次消息指定uuid
),
body=json.dumps(
{
'func': func,
'param': {'a': param[0], 'b': param[1]}
}
)
)
self.connection.process_data_events(time_limit=3)# 與start_consuming()相似,可以設(shè)置超時(shí)參數(shù)
return self.response
rpc = RPC()
print("發(fā)送消息到消費(fèi)者,等待返回結(jié)果")
response = rpc.call(func='del', param=(1, 2))
print("收到來(lái)自消費(fèi)者返回的結(jié)果:{}".format(response))服務(wù)端
import pika
import json
user_info = pika.PlainCredentials('root', 'root')
connection = pika.BlockingConnection(pika.ConnectionParameters('ip', 5672, '/', user_info))
channel = connection.channel()
# 指定接收消息的queue
channel.queue_declare(queue='rpc_queue')
def add_number(a, b):
return a + b
def del_num(a, b):
return a - b
execute_map = {
'add': add_number,
'del': del_num
}
def on_request(ch, method, props, body):
body = json.loads(body.decode('utf-8'))
func = body.get('func')
param = body.get('param')
result = execute_map.get(func)(param.get('a'), param.get('b'))
print('進(jìn)行{}運(yùn)算,并將結(jié)果返回個(gè)消費(fèi)者'.format(func))
ch.basic_publish(exchange='', # 使用默認(rèn)交換機(jī)
routing_key=props.reply_to, # response發(fā)送到該queue
properties=pika.BasicProperties(
correlation_id=props.correlation_id), # 使用correlation_id讓此response與請(qǐng)求消息對(duì)應(yīng)起來(lái)
body=json.dumps({'result': result}))
ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_qos(prefetch_count=1)
# 從rpc_queue中取消息,然后使用on_request進(jìn)行處理
channel.basic_consume(queue='rpc_queue', on_message_callback=on_request)
print(" [x] Awaiting RPC requests")
channel.start_consuming()(七)說(shuō)點(diǎn)啥
對(duì)于rabbitmq的模式還有Routing模式和Topics模式等,這里就不復(fù)述了,其實(shí)pika對(duì)于RabbitMQ的使用還有很多細(xì)節(jié)和參數(shù)值得深究。這篇博客也就是簡(jiǎn)單的記錄下我對(duì)pika操作raabbitmq過(guò)程和簡(jiǎn)單的理解
參考鏈接:
https://www.cnblogs.com/guyuyun/p/14970592.html
https://blog.csdn.net/wohu1104/category_9023593.html
(八)結(jié)語(yǔ)
到此這篇關(guān)于python對(duì)RabbitMQ的簡(jiǎn)單入門(mén)使用的文章就介紹到這了,更多相關(guān)python RabbitMQ使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python中PDF解析利器pdfplumber的使用詳細(xì)教程
pdfplumber是一個(gè)Python庫(kù),專(zhuān)門(mén)用于從PDF文件中提取文本、表格和其他信息,本文將為大家詳細(xì)介紹一下pdfplumber的安裝與詳細(xì)使用,有需要的小伙伴可以參考下2025-04-04
Python學(xué)習(xí)筆記之lambda表達(dá)式用法詳解
這篇文章主要介紹了Python學(xué)習(xí)筆記之lambda表達(dá)式用法,結(jié)合實(shí)例形式詳細(xì)分析了lambda表達(dá)式的概念、功能、原理、組成及相關(guān)使用技巧,需要的朋友可以參考下2019-08-08
Python實(shí)現(xiàn)批量檢測(cè)HTTP服務(wù)的狀態(tài)
本文給大家分享的是一個(gè)使用python實(shí)現(xiàn)的批量檢測(cè)web服務(wù)可用性的腳本代碼,主要功能有測(cè)試一組url的可用性(可以包括HTTP狀態(tài)、響應(yīng)時(shí)間等)并統(tǒng)計(jì)出現(xiàn)不可用情況的次數(shù)和頻率等。2016-10-10
python日記(使用TCP實(shí)現(xiàn)的對(duì)話(huà)客戶(hù)端和服務(wù)器)
這篇文章主要為大家介紹了python使用TCP實(shí)現(xiàn)的對(duì)話(huà)客戶(hù)端和服務(wù)器實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
python pandas合并Sheet,處理列亂序和出現(xiàn)Unnamed列的解決
這篇文章主要介紹了python pandas合并Sheet,處理列亂序和出現(xiàn)Unnamed列的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03
python dataprep庫(kù)簡(jiǎn)化加速數(shù)據(jù)科學(xué)操作
這篇文章主要為大家介紹了python dataprep庫(kù)簡(jiǎn)化加速數(shù)據(jù)科學(xué)操作,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
Python實(shí)現(xiàn)遞歸遍歷文件夾并刪除文件
本文給大家匯總了3個(gè)Python實(shí)現(xiàn)遍歷文件夾并刪除的代碼,主要是給大家分享下這3種方法的實(shí)現(xiàn)思路,有需要的小伙伴可以參考下2016-04-04
python plotly畫(huà)柱狀圖代碼實(shí)例
這篇文章主要介紹了python plotly畫(huà)柱狀圖代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12

