"項目目錄結構"其實也是屬於"可讀性和可維護性"的范疇。
目錄組織方式
關於如何組織一個較好的Python工程目錄結構,已經有一些得到了共識的目錄結構。在Stackoverflow的這個問題上,能看到大家對Python目錄結構的討論。
這里面說的已經很好了,我也不打算重新造輪子列舉各種不同的方式,這里面我說一下我的理解和體會。
假設你的項目名為foo, 我比較建議的最方便快捷目錄結構這樣就足夠了:
Foo/
|-- bin/
| |-- foo
|
|--conf/
| |--__init__.py
| |--settings.py
|
|-- foo/
| |-- tests/
| | |-- __init__.py
| | |-- test_main.py
| |
| |-- __init__.py
| |-- main.py
|
|-- docs/
| |-- conf.py
| |-- abc.rst
|
|-- setup.py
|-- requirements.txt
|-- README
簡要解釋一下:
bin/
: 存放項目的一些可執行文件,當然你可以起名script/
之類的也行。- conf/:存放項目配置文件
foo/
: 存放項目的所有源代碼。(1) 源代碼中的所有模塊、包都應該放在此目錄。不要置於頂層目錄。(2) 其子目錄tests/
存放單元測試代碼; (3) 程序的入口最好命名為main.py
。docs/
: 存放一些文檔。setup.py
: 安裝、部署、打包的腳本。requirements.txt
: 存放軟件依賴的外部Python包列表。README
: 項目說明文件。
除此之外,有一些方案給出了更加多的內容。比如LICENSE.txt
,ChangeLog.txt
文件等,我沒有列在這里,因為這些東西主要是項目開源的時候需要用到。如果你想寫一個開源軟件,目錄該如何組織,可以參考這篇文章。
如何使用不同目錄下的文件
以上圖目錄結構為例,我們在main.py中,使用bin目錄下文件,首先需要找到Foo/目錄,然后才能導入Foo/下的子目錄的模塊,並且需要做到自動獲取,不能寫死,這時候就使用到os模塊
import os
import sys
1、找到文件的絕對路徑
os.path.abspath(__file__) #獲取文件的絕對路徑,包含文件名
2、獲取文件的目錄
os.path.dirname(os.path.abspath(__file__) ) # 例如main.py的目錄是foo/
3、再次獲取文件目錄的父目錄
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__) ))
4、添加到環境變量中
sys.path.append(BASE_DIR)
5、導入需要的目錄
①. import bin
②. from bin import *
二種方式導入,各有優缺點,后續會詳細講解,至此,就可以使用其他目錄的模塊。
=======================以上是我復制來的,以下用上課內容作為舉例。=============================
目錄結構舉例:
start.py中的內容:
#如果我們沒有pycharm,需要部署到linux服務器上運行,那么該文件的路徑需要加到環境變量中 import os,sys res = os.path.abspath(__file__) #__file__是指當前的py文件,這行代碼是取當前文件的絕對路徑,加入到環境變量中。這樣可以在cmd中運行了 base_path = os.path.dirname(os.path.dirname(res))#os.path.dirname(res)是取父目錄,兩層是取上兩級目錄 sys.path.insert(0,base_path)#把這個目錄加入環境變量,這樣就不用寫死了。 # print(res) # print(base_path) # E:\PycharmProjects\day08_python\my_api\bin\start.py # E:\PycharmProjects\day08_python\my_api #以上代碼必須寫在最上面,因為要先加入環境變量,再導入。加上后在任何人電腦運行都可以了 #===============================如果在parcharm中運行,上面的內容可以不用寫====================== from lib.service import server #導入server from lib import user,pay,order #導入其他的模塊 from conf.setting import server_info #導入數據庫配置信息 server.run(**server_info) #啟動服務
setting.py中的內容:
#mysql 配置信息、連接數據庫 mysql_info = { 'host':'xxx.xx.x.xx', 'port':3306, 'user':'xxx, 'password':'123456', 'db':'xxx', 'charset':'utf8', 'autocommit':True } #啟動的配置文件 server_info = { "host":'0.0.0.0', "port":5000, #啟動服務的端口號 'debug':True #是否是調試模式 }
service.py中的內容:
#這個就指提供服務,直接寫一個server.py文件,誰要用就導入 import flask server = flask.Flask(__name__) #把當前這個python文件當做一個服務
tools.py中的內容:
#工具模塊 import pymysql from conf.setting import mysql_info # 導入我們在conf.setting里寫的函數 def my_db(sql):#執行數據庫 conn = pymysql.connect(**mysql_info)#兩個星號把字典自動變成v-k形式 cur = conn.cursor(cursor=pymysql.cursors.DictCursor) cur.execute(sql) res = cur.fetchall() cur.close() conn.close() return res def check_float(s): ''' 這個函數的作用就是判斷傳入的字符串是否是合法的小數 :param s: 傳入一個字符串 :return: True/false ''' s = str(s) if s.count('.')==1: s_split = s.split('.') left,right = s_split if left.isdigit() and right.isdigit(): return True elif left.startswith('-') and left[1:].isdigit() \ and right.isdigit(): return True return False
而user.py、pay.py、order.py分別是用戶登錄注冊、支付、生成訂單項目代碼.