一、elasticsearch for Python之連接篇
前言
現在,我們來學習Python如何操作elasticsearch。
依賴下載
首先,我們必須擁有Python的環境,如何搭建Python環境,請參閱。
要用Python來操作elasticsearch,首先安裝Python的elasticsearch包:
pip install elasticsearch
pip install elasticsearch==6.3.1
# 豆瓣源
pip install -i https://pypi.doubanio.com/simple/ elasticsearch
Python連接elasticsearch
Python連接elasticsearch有以下幾種連接方式:
from elasticsearch import Elasticsearch
# es = Elasticsearch() # 默認連接本地elasticsearch
# es = Elasticsearch(['127.0.0.1:9200']) # 連接本地9200端口
es = Elasticsearch(
["192.168.1.10", "192.168.1.11", "192.168.1.12"], # 連接集群,以列表的形式存放各節點的IP地址
sniff_on_start=True, # 連接前測試
sniff_on_connection_fail=True, # 節點無響應時刷新節點
sniff_timeout=60 # 設置超時時間
)
配置忽略響應狀態碼
es = Elasticsearch(['127.0.0.1:9200'],ignore=400) # 忽略返回的400狀態碼
es = Elasticsearch(['127.0.0.1:9200'],ignore=[400, 405, 502]) # 以列表的形式忽略多個狀態碼
一個簡單的示例
from elasticsearch import Elasticsearch
es = Elasticsearch() # 默認連接本地elasticsearch
print(es.index(index='py2', doc_type='doc', id=1, body={'name': "張開", "age": 18}))
print(es.get(index='py2', doc_type='doc', id=1))
第1個print為創建py2
索引,並插入一條數據,第2個print查詢指定文檔。
查詢結果如下:
{'_index': 'py2', '_type': 'doc', '_id': '1', '_version': 1, 'result': 'created', '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 0, '_primary_term': 1}
{'_index': 'py2', '_type': 'doc', '_id': '1', '_version': 1, 'found': True, '_source': {'name': '張開', 'age': 18}}
see also:[API文檔-Elasticsearch6.3.1文檔](https://elasticsearch-py.readthedocs.io/en/master/api.html#global-options)
二、elasticsearch for Python之操作篇
前言
Python中關於elasticsearch的操作,主要集中一下幾個方面:
- 結果過濾,對於返回結果做過濾,主要是優化返回內容。
- Elasticsearch(簡稱es),直接操作elasticsearch對象,處理一些簡單的索引信息。一下幾個方面都是建立在es對象的基礎上。
- Indices,關於索引的細節操作,比如創建自定義的
mappings
。 - Cluster,關於集群的相關操作。
- Nodes,關於節點的相關操作。
- Cat API,換一種查詢方式,一般的返回都是json類型的,cat提供了簡潔的返回結果。
- Snapshot,快照相關,快照是從正在運行的Elasticsearch集群中獲取的備份。我們可以拍攝單個索引或整個群集的快照,並將其存儲在共享文件系統的存儲庫中,並且有一些插件支持S3,HDFS,Azure,Google雲存儲等上的遠程存儲庫。
- Task Management API,任務管理API是新的,仍應被視為測試版功能。API可能以不向后兼容的方式更改。
結果過濾
print(es.search(index='py2', filter_path=['hits.total', 'hits.hits._source'])) # 可以省略type類型
print(es.search(index='w2', doc_type='doc')) # 可以指定type類型
print(es.search(index='w2', doc_type='doc', filter_path=['hits.total']))
filter_path
參數用於減少elasticsearch返回的響應,比如僅返回hits.total
和hits.hits._source
內容。
除此之外,filter_path
參數還支持*
通配符以匹配字段名稱、任何字段或者字段部分:
print(es.search(index='py2', filter_path=['hits.*']))
print(es.search(index='py2', filter_path=['hits.hits._*']))
print(es.search(index='py2', filter_path=['hits.to*'])) # 僅返回響應數據的total
print(es.search(index='w2', doc_type='doc', filter_path=['hits.hits._*'])) # 可以加上可選的type類型
Elasticsearch(es對象)
- es.index,向指定索引添加或更新文檔,如果索引不存在,首先會創建該索引,然后再執行添加或者更新操作。
# print(es.index(index='w2', doc_type='doc', id='4', body={"name":"可可", "age": 18})) # 正常
# print(es.index(index='w2', doc_type='doc', id=5, body={"name":"卡卡西", "age":22})) # 正常
# print(es.index(index='w2', id=6, body={"name": "鳴人", "age": 22})) # 會報錯,TypeError: index() missing 1 required positional argument: 'doc_type'
print(es.index(index='w2', doc_type='doc', body={"name": "鳴人", "age": 22})) # 可以不指定id,默認生成一個id
- es.get,查詢索引中指定文檔。
print(es.get(index='w2', doc_type='doc', id=5)) # 正常
print(es.get(index='w2', doc_type='doc')) # TypeError: get() missing 1 required positional argument: 'id'
print(es.get(index='w2', id=5)) # TypeError: get() missing 1 required positional argument: 'doc_type'
- es.search,執行搜索查詢並獲取與查詢匹配的搜索匹配。這個用的最多,可以跟復雜的查詢條件。
index
要搜索的以逗號分隔的索引名稱列表; 使用_all 或空字符串對所有索引執行操作。doc_type
要搜索的以逗號分隔的文檔類型列表; 留空以對所有類型執行操作。body
使用Query DSL(QueryDomain Specific Language查詢表達式)的搜索定義。_source
返回_source
字段的true或false,或返回的字段列表,返回指定字段。_source_exclude
要從返回的_source
字段中排除的字段列表,返回的所有字段中,排除哪些字段。_source_include
從_source
字段中提取和返回的字段列表,跟_source
差不多。
print(es.search(index='py3', doc_type='doc', body={"query": {"match":{"age": 20}}})) # 一般查詢
print(es.search(index='py3', doc_type='doc', body={"query": {"match":{"age": 19}}},_source=['name', 'age'])) # 結果字段過濾
print(es.search(index='py3', doc_type='doc', body={"query": {"match":{"age": 19}}},_source_exclude =[ 'age']))
print(es.search(index='py3', doc_type='doc', body={"query": {"match":{"age": 19}}},_source_include =[ 'age']))
- es.get_source,通過索引、類型和ID獲取文檔的來源,其實,直接返回想要的字典。
print(es.get_source(index='py3', doc_type='doc', id='1')) # {'name': '王五', 'age': 19}
- es.count,執行查詢並獲取該查詢的匹配數。比如查詢年齡是18的文檔。
body = {
"query": {
"match": {
"age": 18
}
}
}
print(es.count(index='py2', doc_type='doc', body=body)) # {'count': 1, '_shards': {'total': 5, 'successful': 5, 'skipped': 0, 'failed': 0}}
print(es.count(index='py2', doc_type='doc', body=body)['count']) # 1
print(es.count(index='w2')) # {'count': 6, '_shards': {'total': 5, 'successful': 5, 'skipped': 0, 'failed': 0}}
print(es.count(index='w2', doc_type='doc')) # {'count': 6, '_shards': {'total': 5, 'successful': 5, 'skipped': 0, 'failed': 0}}
- es.create,創建索引(索引不存在的話)並新增一條數據,索引存在僅新增(只能新增,重復執行會報錯)。
print(es.create(index='py3', doc_type='doc', id='1', body={"name": '王五', "age": 20}))
print(es.get(index='py3', doc_type='doc', id='3'))
在內部,調用了index,等價於:
print(es.index(index='py3', doc_type='doc', id='4', body={"name": "麻子", "age": 21}))
但個人覺得沒有index好用!
- es.delete,刪除指定的文檔。比如刪除文章id為
4
的文檔,但不能刪除索引,如果想要刪除索引,還需要es.indices.delete來處理
print(es.delete(index='py3', doc_type='doc', id='4'))
- es.delete_by_query,刪除與查詢匹配的所有文檔。
index
要搜索的以逗號分隔的索引名稱列表; 使用_all 或空字符串對所有索引執行操作。doc_type
要搜索的以逗號分隔的文檔類型列表; 留空以對所有類型執行操作。body
使用Query DSL的搜索定義。
print(es.delete_by_query(index='py3', doc_type='doc', body={"query": {"match":{"age": 20}}}))
- es.exists,查詢elasticsearch中是否存在指定的文檔,返回一個布爾值。
print(es.exists(index='py3', doc_type='doc', id='1'))
- es.info,獲取當前集群的基本信息。
print(es.info())
- es.ping,如果群集已啟動,則返回True,否則返回False。
print(es.ping())
Indices(es.indices)
- es.indices.create,在Elasticsearch中創建索引,用的最多。比如創建一個嚴格模式、有4個字段、並為
title
字段指定ik_max_word
查詢粒度的mappings
。並應用到py4
索引中。這也是常用的創建自定義索引的方式。
body = {
"mappings": {
"doc": {
"dynamic": "strict",
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"url": {
"type": "text"
},
"action_type": {
"type": "text"
},
"content": {
"type": "text"
}
}
}
}
}
es.indices.create('py4', body=body)
- es.indices.analyze,返回分詞結果。
es.indices.analyze(body={'analyzer': "ik_max_word", "text": "皮特和茱麗當選“年度模范情侶”Brad Pitt and Angelina Jolie"})
- es.indices.delete,在Elasticsearch中刪除索引。
print(es.indices.delete(index='py4'))
print(es.indices.delete(index='w3')) # {'acknowledged': True}
- es.indices.put_alias,為一個或多個索引創建別名,查詢多個索引的時候,可以使用這個別名。
index
別名應指向的逗號分隔的索引名稱列表(支持通配符),使用_all對所有索引執行操作。name
要創建或更新的別名的名稱。body
別名的設置,例如路由或過濾器。
print(es.indices.put_alias(index='py4', name='py4_alias')) # 為單個索引創建別名
print(es.indices.put_alias(index=['py3', 'py2'], name='py23_alias')) # 為多個索引創建同一個別名,聯查用
- es.indices.delete_alias,刪除一個或多個別名。
print(es.indices.delete_alias(index='alias1'))
print(es.indices.delete_alias(index=['alias1, alias2']))
- es.indices.get_mapping,檢索索引或索引/類型的映射定義。
print(es.indices.get_mapping(index='py4'))
- es.indices.get_settings,檢索一個或多個(或所有)索引的設置。
print(es.indices.get_settings(index='py4'))
- es.indices.get,允許檢索有關一個或多個索引的信息。
print(es.indices.get(index='py2')) # 查詢指定索引是否存在
print(es.indices.get(index=['py2', 'py3']))
- es.indices.get_alias,檢索一個或多個別名。
print(es.indices.get_alias(index='py2'))
print(es.indices.get_alias(index=['py2', 'py3']))
- es.indices.get_field_mapping,檢索特定字段的映射信息。
print(es.indices.get_field_mapping(fields='url', index='py4', doc_type='doc'))
print(es.indices.get_field_mapping(fields=['url', 'title'], index='py4', doc_type='doc'))
- es.indices.delete_alias,刪除特定別名。
- es.indices.exists,返回一個布爾值,指示給定的索引是否存在。
- es.indices.exists_type,檢查索引/索引中是否存在類型/類型。
- es.indices.flus,明確的刷新一個或多個索引。
- es.indices.get_field_mapping,檢索特定字段的映射。
- es.indices.get_template,按名稱檢索索引模板。
- es.indices.open,打開一個封閉的索引以使其可用於搜索。
- es.indices.close,關閉索引以從群集中刪除它的開銷。封閉索引被阻止進行讀/寫操作。
- es.indices.clear_cache,清除與一個或多個索引關聯的所有緩存或特定緩存。
- es.indices.put_alias,為特定索引/索引創建別名。
- es.indices.get_uprade,監控一個或多個索引的升級程度。
- es.indices.put_mapping,注冊特定類型的特定映射定義。
- es.indices.put_settings,實時更改特定索引級別設置。
- es.indices.put_template,創建一個索引模板,該模板將自動應用於創建的新索引。
- es.indices.rollove,當現有索引被認為太大或太舊時,翻轉索引API將別名轉移到新索引。API接受單個別名和條件列表。別名必須僅指向單個索引。如果索引滿足指定條件,則創建新索引並切換別名以指向新別名。
- es.indices.segments,提供構建Lucene索引(分片級別)的低級別段信息。
Cluster(集群相關)
- es.cluster.get_settigns,獲取集群設置。
print(es.cluster.get_settings())
- es.cluster.health,獲取有關群集運行狀況的非常簡單的狀態。
print(es.cluster.health())
- es.cluster.state,獲取整個集群的綜合狀態信息。
print(es.cluster.state())
- es.cluster.stats,返回群集的當前節點的信息。
print(es.cluster.stats())
Node(節點相關)
- es.nodes.info,返回集群中節點的信息。
print(es.nodes.info()) # 返回所節點
print(es.nodes.info(node_id='node1')) # 指定一個節點
print(es.nodes.info(node_id=['node1', 'node2'])) # 指定多個節點列表
- es.nodes.stats,獲取集群中節點統計信息。
print(es.nodes.stats())
print(es.nodes.stats(node_id='node1'))
print(es.nodes.stats(node_id=['node1', 'node2']))
- es.nodes.hot_threads,獲取指定節點的線程信息。
print(es.nodes.hot_threads(node_id='node1'))
print(es.nodes.hot_threads(node_id=['node1', 'node2']))
- es.nodes.usage,獲取集群中節點的功能使用信息。
print(es.nodes.usage())
print(es.nodes.usage(node_id='node1'))
print(es.nodes.usage(node_id=['node1', 'node2']))
Cat(一種查詢方式)
- es.cat.aliases,返回別名信息。
name
要返回的以逗號分隔的別名列表。format
Accept標頭的簡短版本,例如json,yaml
print(es.cat.aliases(name='py23_alias'))
print(es.cat.aliases(name='py23_alias', format='json'))
- es.cat.allocation,返回分片使用情況。
print(es.cat.allocation())
print(es.cat.allocation(node_id=['node1']))
print(es.cat.allocation(node_id=['node1', 'node2'], format='json'))
- es.cat.count,Count提供對整個群集或單個索引的文檔計數的快速訪問。
print(es.cat.count()) # 集群內的文檔總數
print(es.cat.count(index='py3')) # 指定索引文檔總數
print(es.cat.count(index=['py3', 'py2'], format='json')) # 返回兩個索引文檔和
- es.cat.fielddata,基於每個節點顯示有關當前加載的fielddata的信息。有些數據為了查詢效率,會放在內存中,fielddata用來控制哪些數據應該被放在內存中,而這個
es.cat.fielddata
則查詢現在哪些數據在內存中,數據大小等信息。
print(es.cat.fielddata())
print(es.cat.fielddata(format='json', bytes='b'))
bytes
顯示字節值的單位,有效選項為:'b','k','kb','m','mb','g','gb','t','tb' ,'p','pb'
format
Accept標頭的簡短版本,例如json,yaml
- es.cat.health,從集群中
health
里面過濾出簡潔的集群健康信息。
print(es.cat.health())
print(es.cat.health(format='json'))
- es.cat.help,返回
es.cat
的幫助信息。
print(es.cat.help())
- es.cat.indices,返回索引的信息;也可以使用此命令進行查詢集群中有多少索引。
print(es.cat.indices())
print(es.cat.indices(index='py3'))
print(es.cat.indices(index='py3', format='json'))
print(len(es.cat.indices(format='json'))) # 查詢集群中有多少索引
- es.cat.master,返回集群中主節點的IP,綁定IP和節點名稱。
print(es.cat.master())
print(es.cat.master(format='json'))
- es.cat.nodeattrs,返回節點的自定義屬性。
print(es.cat.nodeattrs())
print(es.cat.nodeattrs(format='json'))
- es.cat.nodes,返回節點的拓撲,這些信息在查看整個集群時通常很有用,特別是大型集群。我有多少符合條件的節點?
print(es.cat.nodes())
print(es.cat.nodes(format='json'))
- es.cat.plugins,返回節點的插件信息。
print(es.cat.plugins())
print(es.cat.plugins(format='json'))
- es.cat.segments,返回每個索引的Lucene有關的信息。
print(es.cat.segments())
print(es.cat.segments(index='py3'))
print(es.cat.segments(index='py3', format='json'))
- es.cat.shards,返回哪個節點包含哪些分片的信息。
print(es.cat.shards())
print(es.cat.shards(index='py3'))
print(es.cat.shards(index='py3', format='json'))
- es.cat.thread_pool,獲取有關線程池的信息。
print(es.cat.thread_pool())
Snapshot(快照相關)
- es.snapshot.create,在存儲庫中創建快照。
repository
存儲庫名稱。snapshot
快照名稱。body
快照定義。
- es.snapshot.delete,從存儲庫中刪除快照。
- es.snapshot.create_repository。注冊共享文件系統存儲庫。
- es.snapshot.delete_repository,刪除共享文件系統存儲庫。
- es.snapshot.get,檢索有關快照的信息。
- es.snapshot.get_repository,返回有關已注冊存儲庫的信息。
- es.snapshot.restore,恢復快照。
- es.snapshot.status,返回有關所有當前運行快照的信息。通過指定存儲庫名稱,可以將結果限制為特定存儲庫。
- es.snapshot.verify_repository,返回成功驗證存儲庫的節點列表,如果驗證過程失敗,則返回錯誤消息。
Task(任務相關)
- es.tasks.get,檢索特定任務的信息。
- es.tasks.cancel,取消任務。
- es.tasks.list,任務列表。
see also:[API文檔-Elasticsearch6.3.1文檔](https://elasticsearch-py.readthedocs.io/en/master/api.html#global-options) | [Fielddata 的過濾](https://www.elastic.co/guide/cn/elasticsearch/guide/current/_fielddata_filtering.html) | [cat nodeattrs](https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-nodeattrs.html) | [cat nodes](https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-nodes.html#cat-nodes) | [任務管理API](https://www.elastic.co/guide/en/elasticsearch/reference/current/tasks.html) | [napshot And Restore]() 歡迎斧正,that's all
三、elasticsearch之使用Python批量寫入數據
順序寫入100條
現在我們如果有大量的文檔(例如10000000萬條文檔)需要寫入es的某條索引中,該怎么辦呢?之前學過的一次插入一條肯定不行:
import time
from elasticsearch import Elasticsearch
es = Elasticsearch()
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs)
print('共耗時約 {:.2f} 秒'.format(time.time() - start))
return res
return wrapper
@timer
def create_data():
""" 寫入數據 """
for line in range(100):
es.index(index='s2', doc_type='doc', body={'title': line})
if __name__ == '__main__':
create_data() # 執行結果大約耗時 7.79 秒
上例為順序向es的s2
索引(該索引已存在)寫入100條文檔,而且值也僅是數字。卻花費了大約7秒左右,這種速度在大量數據的時候,肯定不行。那怎么辦呢?
批量寫入100條
現在,來介紹一種批量寫入的方式:
import time
from elasticsearch import Elasticsearch
from elasticsearch import helpers
es = Elasticsearch()
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs)
print('共耗時約 {:.2f} 秒'.format(time.time() - start))
return res
return wrapper
@timer
def create_data():
""" 寫入數據 """
for line in range(100):
es.index(index='s2', doc_type='doc', body={'title': line})
@timer
def batch_data():
""" 批量寫入數據 """
action = [{
"_index": "s2",
"_type": "doc",
"_source": {
"title": i
}
} for i in range(10000000)]
helpers.bulk(es, action)
if __name__ == '__main__':
# create_data()
batch_data() # MemoryError
我們通過elasticsearch模塊導入helper
,通過helper.bulk
來批量處理大量的數據。首先我們將所有的數據定義成字典形式,各字段含義如下:
_index
對應索引名稱,並且該索引必須存在。_type
對應類型名稱。_source
對應的字典內,每一篇文檔的字段和值,可有有多個字段。
首先將每一篇文檔(組成的字典)都整理成一個大的列表,然后,通過helper.bulk(es, action)
將這個列表寫入到es對象中。
然后,這個程序要執行的話——你就要考慮,這個一千萬個元素的列表,是否會把你的內存撐爆(MemoryError
)!很可能還沒到沒到寫入es那一步,卻因為列表過大導致內存錯誤而使寫入程序崩潰!很不幸,我的程序報錯了。下圖是我在生成列表的時候,觀察任務管理器的進程信息,可以發現此時Python消耗了大量的系統資源,而運行es實例的Java虛擬機卻沒什么變動。
解決辦法是什么呢?我們可以分批寫入,比如我們一次生成長度為一萬的列表,再循環着去把一千萬的任務完成。這樣, Python和Java虛擬機達到負載均衡。
下面的示例測試10萬條數據分批寫入的速度:
import time
from elasticsearch import Elasticsearch
from elasticsearch import helpers
es = Elasticsearch()
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs)
print('共耗時約 {:.2f} 秒'.format(time.time() - start))
return res
return wrapper
@timer
def batch_data():
""" 批量寫入數據 """
# 分批寫
# for i in range(1, 10000001, 10000):
# action = [{
# "_index": "s2",
# "_type": "doc",
# "_source": {
# "title": k
# }
# } for k in range(i, i + 10000)]
# helpers.bulk(es, action)
# 使用生成器
for i in range(1, 100001, 1000):
action = ({
"_index": "s2",
"_type": "doc",
"_source": {
"title": k
}
} for k in range(i, i + 1000))
helpers.bulk(es, action)
if __name__ == '__main__':
# create_data()
batch_data()
注釋的內容是使用列表完成,然后使用生成器完成。結果耗時約93.53 秒。
較勁,我就想一次寫入一千萬條
經過灑家多年臨床經驗發現,程序員為什么掉頭發?都是因為愛較勁!
上面的例子已經不錯了,但是仔細觀察,還是使用了兩次for循環,但是代碼可否優化,答案是可以的,我們直接使用生成器:
import time
from elasticsearch import Elasticsearch
from elasticsearch import helpers
es = Elasticsearch()
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs)
print('共耗時約 {:.2f} 秒'.format(time.time() - start))
return res
return wrapper
@timer
def gen():
""" 使用生成器批量寫入數據 """
action = ({
"_index": "s2",
"_type": "doc",
"_source": {
"title": i
}
} for i in range(100000))
helpers.bulk(es, action)
if __name__ == '__main__':
# create_data()
# batch_data()
gen()
我們將生成器交給es去處理,這樣,Python的壓力更小了,你要說Java虛擬機不是壓力更大了,無論是分批處理還是使用生成器,虛擬機的壓力都不小,寫入操作本來就耗時嘛!上例測試結果大約是耗時90秒鍾,還行,一千萬的任務還是留給你去測試吧!
歡迎斧正,that's all
四、python啟動elasticsearch
前言
你肯能受夠了,每天(如果你每天電腦都關機的話)都要手動打開目錄去找到es和kibana的啟動文件去手動啟動兩個程序。那現在有好的方式解決嗎?答案是有的呀!我們可以寫一個腳本去自動的執行嘛!
測試環境:
- windows 10
- elasticsearch6.5.4
- kibana6.5.4
制作Python啟動es和kibana啟動腳本
import os
import time
import random
elasticsearch = r'C:\elasticsearch-6.5.4\bin\elasticsearch.bat'
kibana = r'C:\elasticsearch-6.5.4\kibana-6.5.4-windows-x86_64\bin\kibana.bat'
def progress_bar(item):
for i in range(11, 0, -1):
if item == 'kibana':
time.sleep(random.random() + 0.8)
else:
time.sleep(random.random() + 0.4)
res = '\r%s正在加載:%s %s%%\n' % (item, ('████' * (12 - i)), (11 - i) * 10) if i == 1 else '\r%s正在加載:%s %s%%' % (
item,
(
'████' * (
12 - i)),
(11 - i) * 10)
print('\033[31m%s\033[0m' % res, end='')
def run():
for item in [(elasticsearch, 'elasticsearch'), (kibana, 'kibana')]:
os.system('start %s' % item[0])
progress_bar(item[1])
time.sleep(10)
if __name__ == '__main__':
run()
上面的簡單腳本中,我們借助os.system
來完成腳本啟動工作,並添加了進度條。
每次想要啟動兩個程序的時候,我們只需要在Python環境下執行該腳本即可。
制作一鍵啟動腳本
那么,我們的系統環境或許沒有Python環境,又想使用該腳本,這就要使該腳本能脫離Python環境獨立運行,比如說將該腳本打包成exe可執行文件等。那么怎么做呢?你可能想到py2exe和pyinstaller,這里以pyinstaller為例,我們將Python腳本打包成exe可執行文件。
首先要下載pyinstaller:
pip install pyinstaller
然后,在終端中執行要打包的文件:
F:\>pyinstaller -F run.py
如上命令,比如我們終端中的路徑在F
盤根目錄,腳本文件如果也在這個目錄下的話,可以直接使用上述命令執行。結果會生成如一個文件兩個目錄:
其中,build和run.spec為生成時的依賴文件。在執行完畢后,可以刪掉,最終的可執行文件run.exe
在dist目錄內,這個可執行文件,我們可以放到本機的任何地方,比如桌面,非常方便。
歡迎斧正,that's all