您好,登錄后才能下訂單哦!
在Python中,一個.py文件就稱為一個模塊。
最大的好處是提高了代碼的可維護性。其次,編寫代碼不必從零開始。當一個模塊編寫完成,就可以被其他地方引用。我們在編寫程序的時候,也經常引用其他模塊,包括Python內置的模塊和第三方的模塊。
使用模塊可以避免函數名和變量名的沖突。每個模塊有獨立的命名空間,因此相同名字的函數和變量完全可以分別存在不同的模塊中,所以,我們在編寫模塊時,不必考慮名字會和其他模塊沖突。
模塊分為三種:
內置標準模塊(又稱標準庫)執行help('modules')查看所有python自帶模塊列表,如os,sys等等
第三方開源模塊,可通過pip install模塊名 聯網安裝
自定義模塊
import module
from module import xx
from module.xx.xx import xx as rename
from module.xx.xx import *
"注意:模塊一旦被調用,即相當于執行了另外一個py文件里的代碼"
創建一個.py文件,就可以稱為模塊,就可以在另外一個程序中導入
我們會發現,自己寫的模塊只能在當前路徑下的程序中才能導入,換一個目錄再導入自己的模塊就報錯說找不到了,這主要是與導入路徑有關
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import sys
print(sys.path)
E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
['E:\\PythonProject\\python-test\\BasicGrammer', 'E:\\PythonProject\\python-test\\BasicGrammer', 'D:\\software\\pycharm\\install\\PyCharm 2019.1.1\\helpers\\pycharm_display', 'E:\\PythonProject\\python-test\\venvP3\\Scripts\\python36.zip', 'D:\\software2\\Python3\\install\\DLLs', 'D:\\software2\\Python3\\install\\lib', 'D:\\software2\\Python3\\install', 'E:\\PythonProject\\python-test\\venvP3', 'E:\\PythonProject\\python-test\\venvP3\\lib\\site-packages', 'E:\\PythonProject\\python-test\\venvP3\\lib\\site-packages\\setuptools-40.8.0-py3.6.egg', 'E:\\PythonProject\\python-test\\venvP3\\lib\\site-packages\\pip-19.0.3-py3.6.egg', 'D:\\software\\pycharm\\install\\PyCharm 2019.1.1\\helpers\\pycharm_matplotlib_backend']
Process finished with exit code 0
前兩個是當前.py程序所在的路徑,python解釋器會按照上面列表中的路徑依次去尋找要導入的.py文件,找到了就立刻導入,不再繼續往后找。
注意:可能有的人第一個元素為空(""),是代表當前目錄,所以自己定義的模塊在當前目錄會被優先導入。
https://pypi.org/ 是開源模塊庫
安裝方式1:
直接下載.tar.gz,解壓后進入目錄,執行下面命令完成安裝
編譯源碼:python3 setup.py build
安裝源碼:python3 setup.py install
安裝方式2:
pip3 install paramiko
pip會自動到開源模塊庫中下載安裝包并安裝
軟件一般會自動安裝到python的安裝目錄下的site-packages中
/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是模塊名
下載后,直接導入使用就可以
#coding:utf-8
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.1.108', 22, 'alex', '123')
stdin, stdout, stderr = ssh.exec_command('df')
print(stdout.read())
ssh.close();
執行命令 - 通過用戶名和密碼連接服務器
.
└── my_proj
├── crm #代碼目錄
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── manage.py
└── my_proj #配置文件目錄
├── settings.py
├── urls.py
└── wsgi.py
像上面那樣,一個文件夾管理多個模塊文件,這個文件夾就被稱為包
不同包之間的模塊導入
"crm/views.py內容"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
def sayhi():
print("hello")
"manage.py中內容"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from crm import views
views.sayhi()
>python2 E:/PythonProject/python-test/BasicGrammer/mypro/manage.py
Traceback (most recent call last):
File "E:/PythonProject/python-test/BasicGrammer/mypro/manage.py", line 4, in <module>
from crm import views
ImportError: No module named crm
"python2中,會報模塊找不到,為什么?"
包是文件夾,但該文件夾下必須存在__init__.py文件,改文件的內容可以為空。__init__.py用于標識當前文件夾就是一個包。
在crm目錄下創建一個空文件__init__.py,在執行一次就可以了
(venvP3) E:\PythonProject\python-test\BasicGrammer\mypro\crm>dir
E:\PythonProject\python-test\BasicGrammer\mypro\crm 的目錄
2019/05/05 周日 15:37 95 views.py
2019/05/05 周日 15:42 314 views.pyc
2019/05/05 周日 15:42 61 __init__.py
>python2 E:/PythonProject/python-test/BasicGrammer/mypro/manage.py
hello
>python3 E:/PythonProject/python-test/BasicGrammer/mypro/manage.py
hello
(venvP3) E:\PythonProject\python-test\BasicGrammer>
"注意:在Python3中,即使目錄下沒有__Init__.py文件也能創建成功,應該是解釋器優化所致,但創建包最好還是加上__init__.py文件"
實際使用中,我們會使用pycharm創建一個package時,會自動創建__init__.py,不需要我們手動創建
目錄結構如下
.
├── __init__.py
├── crm
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ ├── views.py
├── manage.py
└── proj
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
根據上面的結構,如何實現在crm/views.py里導入proj/settings.py模塊?
直接導入的話,會報錯,說找到不模塊
因為當前入口是views.py,那么當前sys.path中的當前路徑是crm,在crm下沒有proj
$ python3 views.py
Traceback (most recent call last):
File "views.py", line 2, in <module>
from proj import settings
ModuleNotFoundError: No module named 'proj'
那要怎么辦呢,可以自己設置環境變量,把crm的父級路徑添加到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!')
print(settings.DATABASES)
$ python3 views.py
/Users/alex/Documents/work/PyProjects/luffy_課件/21天入門/chapter4-常用模塊/packages/my_proj
---my proj init--- #proj/__init__.py輸出
in proj/settings.py #proj/settings.py輸出
{'host': 'localhost'}
那此時依舊執行views.py,在proj/settings.py寫上import urls會有問題么?
DATABASES= {
'host':'localhost'
}
import urls #這行剛加的
print('in proj/settings.py')
結果報錯了
ModuleNotFoundError: No module named 'urls'
因為程序入口是views.py,剛剛加入環境變量的是crm和proj的父級目錄,當前目錄又是crm目錄,所以在這兩個路徑下都沒有urls.py需要改成下面這樣
DATABASES= {
'host':'localhost'
}
from proj import urls #proj的父級目錄已經添加到sys.path里,可以直接在proj中找到urls.py
print('in proj/settings.py')
在linux里可以通過cd ..回到上一層目錄 ,cd ../.. 往上回2層,這個..就是指相對路徑,在python里,導入也可以通過..
例如:
.
├── __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)
執行結果報錯了
Traceback (most recent call last):
File "my_proj/crm/views.py", line 4, in <module>
from ..proj import settings
SystemError: Parent module '' not loaded, cannot perform relative import
或有人看到下面的錯誤
ValueError: attempted relative import beyond top-level package
其實這兩個錯誤的原因歸根結底是一樣的:
在涉及到相對導入時,package所對應的文件夾必須正確的被python解釋器視作package,而不是普通文件夾。否則由于不被視作package,無法利用package之間的嵌套關系實現python中包的相對導入。
文件夾被python解釋器視作package需要滿足兩個條件:
1.文件夾中必須有__init__.py文件,該文件可以為空,但必須存在該文件。
2.不能作為頂層模塊來執行該文件夾中的py文件(即不能作為主函數的入口)。
所以這個問題的解決辦法就是,既然你在views.py里執行了相對導入,那就不要把views.py當作入口程序,可以通過上一級的manage.py調用views.py
.
├── __init__.py
├── crm
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ ├── views.py #from ..proj import settings
├── manage.py #from crm import views
└── proj
├── __init__.py
├── settings.py #from .import urls
├── urls.py
└── wsgi.py
事實證明還是報錯
ValueError: attempted relative import beyond top-level package
但把from ..proj import settings 改成from . import models 后卻執行成功了,為什么呢?
from ..proj import settings 會報錯的原因是,這句代碼會把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支持相對導入,但對模塊間的路徑關系要求比較嚴格,處理不當就容易出錯,所以并不建議在項目里經常使用。"
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。