摘要:Python
,Pycharm
工程結(jié)構(gòu)
一個通用的Python工程目錄結(jié)構(gòu)如下
MY_PROJECT
├── bin
│ ├── run_inc.sh
│ └── run_stored.sh
├── docs
│ └── config.yml
├── logs
│ └── detail.log
├── my_project
│ ├── data
│ │ └── dictionary.txt
│ ├── inc_main.py
│ ├── main
│ │ ├── __init__.py
│ │ ├── predict.py
│ │ ├── preprocessing.py
│ │ ├── rank.py
│ │ └── recall.py
│ ├── stored_main.py
│ └── utils
│ ├── config.py
│ ├── __init__.py
│ ├── md5_utils.py
│ └── mysql_utils.py
├── README.md
└── requirements.txt
項目名
:根目錄MY_PROJECT
下創(chuàng)建項目目錄my_project
拦惋,不要把項目代碼直接暴露在根目錄下,項目目錄下包含源代碼中的所有模塊安寺、包厕妖,程序入口以main.py命名暴露在項目目錄下,例子中是inc_main和stored_main增存量程序入口
bin
: 存放項目的一些可執(zhí)行文件
docs
: 存放一些文檔我衬,配置文件在該目錄下
logs
:存儲日志文件
requirements.txt
: 存放軟件依賴的外部Python包列表
README.md
: 項目說明文件
__init__.py的作用
有__init__.py的目錄是Python包,目錄下的Python腳本叫做模塊饰恕,沒有的只是普通目錄挠羔,一般__init__.py都為空,當(dāng)導(dǎo)入帶有__init__.py的包時都會先去執(zhí)行__init__.py腳本埋嵌,因此可以在__init__.py做相應(yīng)的初始化
破加。
同目錄下引入包和模塊
此時需要在rank模塊里面引用recall的方法,直接以
模塊名稱開頭
進行引用即可此時可以正常運行雹嗦,但是模塊爆紅范舀,在嘗試一下Python console控制臺運行合是,報錯找不到模塊
解決方案是在Pycharm的Settings中增加Python console的設(shè)置,增加source目錄加入到尋找包的搜索列表中
并且在項目結(jié)構(gòu)中指定source目錄如下
添加之后main目錄變?yōu)樗{(lán)色锭环,并且代碼在Python console可以運行聪全,而且紅線消失
跨目錄引用自定義包
在某個Python腳本中只能引用和該腳本同一目錄級別下
的Python模塊,引入非同級下的文件直接報錯找不到模塊辅辩,需要使用sys.path.append
方法添加路徑到包搜索路徑难礼,比如在main下的模塊需要引用utils下的模塊方法
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
from utils.config import get_string
print(get_string("a"))
當(dāng)在linux機器運行的時候采用絕對路徑
,如果是相對路徑os.path.dirname(__file__)返回為空字符串
root@ubuntu:~/../MY_PROJECT/my_project# python /home/.../MY_PROJECT/my_project/main/rank.py
1
如果是相對路徑還是報錯
root@ubuntu:~/.../MY_PROJECT/my_project/main# python rank.py
Traceback (most recent call last):
File "rank.py", line 6, in <module>
from utils.config import get_string
ModuleNotFoundError: No module named 'utils'
但是在Pycharm中可以正常運行玫锋,因此最好在Python腳本中對__file__使用絕對路徑os.path.abspath
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from utils.config import get_string
print(get_string("a"))
讀取自定義文件
sys.path是自動搜索Python包模塊的路徑蛾茉,對于其他文件需要手動修改路徑
,使得路徑相對于當(dāng)下模塊的路徑正確撩鹿,否則找不到文件
utils包下config.py模塊讀取根目錄下docs目錄下的yaml配置文件的代碼實例如下谦炬,使用
os.path.join
拼接目錄得到絕對路徑
import os
import yaml
BASIC_PATH = (os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
YAML_FILE = os.path.join(BASIC_PATH, "./docs/config.yml")
def load_yaml_config(yaml_file):
with open(yaml_file) as f:
config = yaml.load(f, Loader=yaml.FullLoader)
return config
conf = load_yaml_config(YAML_FILE)
def get_string(key: str, default: str = None):
if key in conf.keys():
return str(conf.get(key))
return default
if __name__ == '__main__':
res = get_string("a")
print(res)
自動輸出requirements.txt
下載第三方依賴包pipreqs
pip install pipreqs
打開Pycharm的終端,在項目的根目錄下輸入如下命令
(base) root@ubuntu:~/.../MY_PROJECT# pipreqs . --force
INFO: Successfully saved requirements file in ./requirements.txt
PyYAML==5.4.1
scikit_learn==0.24.1
使用發(fā)現(xiàn)導(dǎo)出的包和實際開發(fā)環(huán)境中的包版本不一致节沦,還得謹(jǐn)慎使用
可執(zhí)行文件.sh
在bin下指定了兩個可執(zhí)行文件键思,分別對應(yīng)項目目錄下的增量和存量main腳本,內(nèi)容如下
#!/bin/bash
cd ../my_project
python3 inc_main.py
root@ubuntu:~/.../MY_PROJECT/bin# chmod +x run_inc.sh
root@ubuntu:~/.../MY_PROJECT/bin# bash run_inc.sh
1
finished!