Python項目打包
python本身是一種腳本語音,發布的話,直接發布源代碼就可以了,但是,可能有些公司並不想發布源代碼,那么,就涉及到打包了,網上有很的打包教程,其實我也沒有認真去研究,因為我只想簡單點,所以,我打算直接編譯成pyc二進制文件來發布,就可以了。
問題
- 編譯成二進制文件(*.pyc)之后,文件名都變了,模塊之間怎么引用?
- 網上的例子,大都是對單個文件編譯的介紹,對整個目錄編譯的話,也都是輸出到相應的文件夾下,需要單獨抽取出來,發布。
解決問題
- 一般編譯之后的文件命名為:比如我的源文件為test.py,編譯后輸出到__pycache__文件夾下test.cpython-37.pyc,要保持模塊引用不改變,那么必須在編譯之后重命名為test.pyc文件,批注:37是因為我使用的python版本為3.7.4所以含有37,其他版本要做相應的調整。
- 需要按照原來的項目目錄結構輸出pyc文件才能保證模塊之間調用沒有問題。
編碼實現
import os
import shutil
import compileall
from pathlib import Path
versions = ".cpython-37"
pycache = "__pycache__"
build_dir = "build"
root = os.getcwd()
print("正在編譯文件...請等待...")
compileall.compile_dir(root) # 編譯
build = Path(root,build_dir)
if build.exists():
print("正在移除build目錄...請等待...")
shutil.rmtree(build)
print("正在復制文件...請等待...")
shutil.copytree(root,build) # 復制文件到build目錄
for root, dirs, files in os.walk(build): # 開始遍歷文件
# root 表示當前正在訪問的文件夾路徑
# dirs 表示該文件夾下的子目錄名list
# files 表示該文件夾下的文件list
# 遍歷文件
for f in files:
src = os.path.join(root, f)
if f.endswith(".py"):
os.remove(src)
elif f.endswith(".pyc"):
upper_dir = root.replace(pycache,"")
dst = os.path.join(upper_dir,f.replace(versions,""))
shutil.copy(src,dst)
for root, dirs, files in os.walk(build): # 移除緩存文件夾
print("正在移除緩存文件...請等待...")
if root.endswith(pycache):
shutil.rmtree(root)
print("打包完成...請查看目錄:"+str(build))
注意文件中版本號的調整,基本上是通用的,所有的python項目都可以用拿來就用。代碼很簡單,但是很實用。
