一、模塊
1、模塊的定義:
為了編寫可維護的代碼,我們把很多函數分組,分別放到不同的文件里,這樣,每個文件包含的代碼就相對較少,
很多編程語言都采用這種組織代碼的方式。在Python中,一個.py文件就稱之為一個模塊(Module)。
2、使用模塊的好處:
<1> 提高了代碼的可維護性,其次,可以被其他地方引用。
<2> 使用模塊可以避免函數名和變量名沖突。
3、模塊分類
分為三種:
<1> 內置標准模塊(又稱標准庫)執行help('modules')查看所有python自帶模塊列表。
<2> 第三方開源模塊,可通過pip install 模塊名 聯網安裝。
<3> 自定義模塊
4、模塊調用的方法
import module
from module import xx
from module.xx.xx import xx as rename
from module.xx.xx import
注意:模塊一旦被調用,就相當於執行了另一個py文件里的代碼。
5、自定義模塊
所謂自定義模塊,就是創建了一個.py文件,就可以稱之為模塊,可以在另一個程序里導入。
6、模塊查找路徑
自定義模塊只能在當前路徑下的程序里才能導入,換一個目錄再導入自己的模塊就報錯說找不到了, 這是為什么?
這與導入路徑有關
import sys
print(sys.path)
輸出:['', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6'
,
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages']
python解釋器會按照列表順序去依次到每個目錄下去匹配你要導入的模塊名,只要在一個目錄下匹配到了該模塊名,就立刻導入,不再繼續往后找。
注意:列表第一個元素為空,即代表當前目錄,所以你自己定義的模塊在當前目錄會被優先導入。
7、開源模塊安裝與使用
https://pypi.python.org/pypi 是python的開源模塊庫,如何從這個平台上下載代碼呢?
1.直接在上面這個頁面上點download,下載后,解壓並進入目錄,執行以下命令完成安裝
編譯源碼 python setup.py build
安裝源碼 python setup.py install
2、直接通過pip安裝
pip3 install paramiko #parmiko 是模塊名
pip命令會自動下載模塊包並完成安裝,軟件一般會被自動安裝你python安裝目錄的這個子目錄里
/your_python_install_path/3.6/lib/python3.6/site-packages
pip命令默認會連接在國外的python官方服務器下載,速度比較慢,你還可以使用國內的豆瓣源,數據會定期同步國外官網,速度快好多
sudo pip install -i http://pypi.douban.com/simple/ alex_sayhi
--trusted-host pypi.douban.com #alex_sayhi是模塊名
二、包(package)
└── my_proj ├── crm #代碼目錄 │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ └── views.py ├── manage.py └── my_proj #配置文件目錄 ├── settings.py ├── urls.py
像上面這樣,一個文件夾管理多個模塊文件,這個文件夾就被稱為包。
crm/views.py內容
def sayhi(): print('hello world!')
通過manage.py調用
from crm import views views.sayhi()
執行manage.py,pthon3中可以執行,但python2會出問題。
包就是文件夾,但該文件夾下必須存在 __init__.py 文件, 該文件的內容可以為空。__int__.py用於標識當前文件夾是一個包。
在crm目錄下創建一個空文件__int__.py ,再執行一次就可以了。
注意,在python3里,即使目錄下沒__int__.py文件也能創建成功,猜應該是解釋器優化所致,但創建包還是要記得加上這個文件 。
跨模塊導入
如何實現在crm/views.py
里導入proj/settings.py
模塊呢?
直接導入會報錯找不到模塊。
因為路徑找不到,proj/settings.py 相當於是crm/views.py的父親(crm)的兄弟(proj)的兒子(settings.py),
settings.py算是views.py的表弟啦,在views.py里只能導入同級別兄弟模塊代碼,或者子級別包里的模塊,
根本不知道表弟表哥的存在。該怎么做呢?
添加環境變量,把父親級的路徑添加到sys.path中,就可以了,這樣導入 就相當於從父親級開始找模塊了。
# crm/views.py中添加環境變量
import sys ,os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #__file__的是打印當前被執行的模塊.py文件相對路徑,注意是相對路徑
print(BASE_DIR) sys.path.append(BASE_DIR) from proj import settings def sayhi(): print('hello world!')
注意;此時在proj/settings.py寫上import urls會有問題, 因為現在的程序入口是views.py , 你在settings.py導入import urls,
其實相當於在crm目錄找urls.py,而不是proj目錄,若想正常導入,要改成如下:
from proj import urls #proj這一層目錄已經添加到sys.path里,可以直接找到
print('in proj/settings.py')
三、絕對導入和相對導入
├── __init__.py ├── crm │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ ├── views.py #from ..proj import settings
├── manage.py └── proj ├── __init__.py ├── settings.py #from .import urls
├── urls.py └── wsgi.py
# views.py里代碼
from ..proj import settings def sayhi(): print('hello world!') print(settings.DATABASES)
這樣執行會報錯。
在涉及到相對導入時,package所對應的文件夾必須正確的被python解釋器視作package,而不是普通文件夾。
否則由於不被視作package,無法利用package之間的嵌套關系實現python中包的相對導入。
文件夾被python解釋器視作package需要滿足兩個條件:
- 文件夾中必須有__init__.py文件,該文件可以為空,但必須存在該文件。
- 不能作為頂層模塊來執行該文件夾中的py文件(即不能作為主函數的入口)。
所以這個問題的解決辦法就是,既然你在views.py里執行了相對導入,那就不要把views.py當作入口程序,
可以通過上一級的manage.py調用views.py。
from .. import models
會報錯的原因是,這句代碼會把manage.py所在的這一層視作package,但實際上它不是,
因為package不能是頂層入口代碼,若想不出錯,只能把manage.py往上再移一層。
# 正確的代碼目錄結構如下
packages/ ├── __init__.py ├── manage.py #from my_proj.crm import views
└── my_proj ├── crm │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ ├── views.py #from . import models; from ..proj import settings
└── proj ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py
再執行manage.py就不會報錯了。
注意:雖然python支持相對導入,但對模塊間的路徑關系要求比較嚴格,處理不當就容易出錯,
不建議使用。
以上內容摘錄與總結於:https://www.luffycity.com/python-book/di-4-zhang-python-ji-chu-2014-chang-yong-mo-kuai/mo-kuai-3001-bao-jie-shao-he-xiang-guan-yu-fa.html