這是一篇舊文,編寫於2017年,用於公司內部交流。整理更新後於2019年04月06日重發,內容有效期樂觀估計半年,閱讀請注意保質期。html
python當前主要有2個release版本 Python 2.7.16 和 Python 3.7.3 ,這兩個版本在一些語法上存在較大差別。python
若是你從網上下載了一段python代碼,卻運行不起來,首先要排除的是python版本問題。好比下面這個 hello_python.py ,代碼很是簡單,就一句打印 hello,world
到屏幕上。react
print "hello,world" 複製代碼
若是你使用python2.7,恭喜你能夠很好的跑起來,以下:git
(python27) ➜ python hello_python.py
hello,world
複製代碼
若是你使用的是python3,可能就實現從入門到放棄:(docker
(python37) ➜ python hello_python.py File "hello_python.py", line 3 print "hello,world" ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print("hello,world")? 複製代碼
python3 中讓代碼正常運行的辦法和提示同樣,修改語句爲
print("hello,world")
npm
python2.7已經 「過期」,pip運行是會提示:django
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7. 複製代碼
現實情況倒是一些庫的版本問題或者歷史遺留問題,可能須要在python2和python3之間切換。flask
python語言應用很是普遍,涉及服務器腳本、爬蟲、程序開發、科學計算,大數據,機器學習等。不一樣的場景下,使用的庫是有差別:windows
使用場景 | 經常使用庫 |
---|---|
程序開發 | flask/django |
爬蟲 | requests/beautifulsoup4/scrapy |
科學計算 | pandas/numpy/matplotlib |
... | ... |
庫又會依賴另外的庫,這樣若是所有安裝在一個環境裏,難以規避庫的版本衝突。後端
鑑於python版本差別和使用場景差別,推薦使用虛擬環境進行隔離管理,省事很多。
使用虛擬環境以前,咱們先花一點點時間來了解python的包安裝工具 pip , 相信我這很簡單。
Python的最大的優點之一是豐富的庫,跨平臺,在UNIX,Windows和Macintosh兼容很好。
安裝這些庫,讓開發速度飈起來,就須要使用 pip。
下面使用pip
安裝requests
庫示例:
(py27studio) ➜ pytest pip install requests Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting requests Downloading https://pypi.tuna.tsinghua.edu.cn/packages/f1/ca/10332a30cb25b627192b4ea272c351bce3ca1091e541245cccbace6051d8/requests-2.20.0-py2.py3-none-any.whl (60kB) 100% |████████████████████████████████| 61kB 1.5MB/s Collecting chardet<3.1.0,>=3.0.2 (from requests) Using cached https://pypi.tuna.tsinghua.edu.cn/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl Collecting urllib3<1.25,>=1.21.1 (from requests) Downloading https://pypi.tuna.tsinghua.edu.cn/packages/62/00/ee1d7de624db8ba7090d1226aebefab96a2c71cd5cfa7629d6ad3f61b79e/urllib3-1.24.1-py2.py3-none-any.whl (118kB) 100% |████████████████████████████████| 122kB 1.5MB/s Collecting certifi>=2017.4.17 (from requests) Downloading https://pypi.tuna.tsinghua.edu.cn/packages/56/9d/1d02dd80bc4cd955f98980f28c5ee2200e1209292d5f9e9cc8d030d18655/certifi-2018.10.15-py2.py3-none-any.whl (146kB) 100% |████████████████████████████████| 153kB 287kB/s Collecting idna<2.8,>=2.5 (from requests) Downloading https://pypi.tuna.tsinghua.edu.cn/packages/4b/2a/0276479a4b3caeb8a8c1af2f8e4355746a97fab05a372e4a2c6a6b876165/idna-2.7-py2.py3-none-any.whl (58kB) 100% |████████████████████████████████| 61kB 131kB/s Installing collected packages: chardet, urllib3, certifi, idna, requests Successfully installed certifi-2018.10.15 chardet-3.0.4 idna-2.7 requests-2.20.0 urllib3-1.24.1 複製代碼
從示例可見 pip 的2個特色:
快速安裝。命令行中一鍵安裝完成。
自動解決依賴。在安裝requests的同時還安裝了: chardet, urllib3, certifi, idna 而且自動解決各個庫的版本問題, 通常狀況下咱們不用關心這些細節。
下面是 pip的一些經常使用命令
# 列出庫列表 pip list # 升級pip pip install pip -U # 安裝指定的庫 pip install name # 刪除指定的庫 pip uninstall name 複製代碼
瞭解 pip 的經常使用命令後,能夠愉快的寫代碼了。逐漸你會遇到在不一樣機器上同步庫或者同事使用你的代碼,須要安裝相同的庫。這時候你就須要pip的2個進階命令了。
# 將當期環境中的庫列表造成 requirements.txt 文件 pip freeze >requirements.txt # 根據 requirements.txt 批量安裝庫 pip install -r requirements.txt 複製代碼
你可使用下面2個命令,獲取pip的使用幫助,瞭解更多
pip help pip install -h 複製代碼
因爲PyPI服務位於國外,訪問起來比較緩慢,可使用國內的一些源進行加速
設置pip使用國內源 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 複製代碼
一些其它的源: 豆瓣源:pypi.douban.com/simple/ 阿里雲源: mirrors.aliyun.com/pypi/simple…
其它平臺/語言也有相似的解決方案,若是你有興趣可使用下面關鍵字自行了解。
yum/apt/npm/brew/maven...
Python 從3.3 版本開始,自帶了一個虛擬環境 venv,在 PEP-405 中能夠看到它的詳細介紹。
在 *nix 系統上,能夠直接執行 pyvenv ./blog-env
來建立一個虛擬環境。在 Windows 系統上,則可使用 python -m venv ./blog-env
來建立, 這個命令也能夠用於 *nix 系統,推薦使用。
venv建立的虛擬環境,建議就在項目目錄,這樣使用起來更方便,沒有記憶負擔。
建立完成後 *nix 系統上, 使用 source ./blog-env/bin/activate
進入虛擬環境,window系統上,使用 Scripts\\activate.bat
,效果以下:
➜ blog source ./blog-env/bin/activate (blog-env) ➜ blog 複製代碼
注意在命令提示符以前新出現的 (blog-env) 標識進入了新的虛擬環境。
這樣很方便就得到了一個隔離的python環境。
pipenv是Kenneth Reitz推出的python包依賴工具, kr就是大名鼎鼎requests的做者。pipenv號稱Python Dev Workflow for Humans, 實力可見一斑。
介紹pipenv以前,咱們先看venv存在的問題。我這裏有一個django項目,使用django-rest-framework提供RestFul api服務, 利用jwt進行先後端認證,項目安裝完後依賴大概以下:
(wxsc) ➜ wordpress pip list
Package Version
----------------------- ----------
asn1crypto 0.24.0
certifi 2018.10.15
cffi 1.11.5
chardet 3.0.4
coreapi 2.3.3
coreschema 0.0.4
cryptography 2.3.1
diff-match-patch 20181111
Django 2.0.5
django-crispy-forms 1.7.2
django-filter 2.0.0
django-formtools 2.1
django-import-export 1.1.0
django-reversion 3.0.0
djangorestframework 3.9.0
djangorestframework-jwt 1.11.0
et-xmlfile 1.0.1
future 0.16.0
httpie 1.0.0
httplib2 0.12.0
idna 2.7
itypes 1.1.0
jdcal 1.4
Jinja2 2.10
Markdown 3.0.1
MarkupSafe 1.1.0
odfpy 1.3.6
openpyxl 2.5.10
pip 18.1
pipenv 2018.11.14
pycparser 2.19
Pygments 2.2.0
PyJWT 1.6.4
PyMySQL 0.9.2
pytz 2018.5
PyYAML 3.13
requests 2.20.1
setuptools 40.6.2
six 1.11.0
tablib 0.12.1
unicodecsv 0.14.1
uritemplate 3.0.0
urllib3 1.24.1
virtualenv 16.1.0
virtualenv-clone 0.4.0
wheel 0.32.2
xlrd 1.1.0
XlsxWriter 1.1.2
xlwt 1.3.0
複製代碼
前先後後大約安裝了50個包,最後徹底不清楚,那些是我直接安裝的,那些是間接安裝的,pipenv能夠解決這個問題。
pipenv 安裝很方便:
$ pip install pipenv
複製代碼
若是標準版本仍是python2.7,則可使用 pip3 install pipenv
pipenv使用起來也很方便。接下來咱們一塊兒瞭解這個過程。
建立一個新的工做目錄myproject
,使用下面命令建立虛擬環境,建立完成後目錄下會生成一個Pipfile文件。
$ pipenv --three Creating a virtualenv for this project… Pipfile: /private/tmp/myproject/Pipfile Using /Library/Frameworks/Python.framework/Versions/3.7/bin/python3 (3.7.1) to create virtualenv… ✔ Complete Using base prefix '/Library/Frameworks/Python.framework/Versions/3.7' New python executable in /Users/tu/codes/venv/myproject-7Ev2diGY/bin/python3 Also creating executable in /Users/tu/codes/venv/myproject-7Ev2diGY/bin/python Installing setuptools, pip, wheel... done. Running virtualenv with interpreter /Library/Frameworks/Python.framework/Versions/3.7/bin/python3 Virtualenv location: /Users/tu/codes/venv/myproject-7Ev2diGY Creating a Pipfile for this project… 複製代碼
查看虛擬環境的實際目錄,瞭解python命令路徑(能夠用於配合pycharm選擇解釋器)。
$ pipenv --venv
$ pipenv --py
複製代碼
pipenv 的虛擬環境會統一存放,不會在項目路徑下
安裝軟件包。包安裝完成後,會在項目路徑下生成Pipfile.lock文件。
$ pipenv install requests
$ pipenv install django
複製代碼
注意: 這裏不是使用 pip 進行包安裝,而是使用 pipenv 。
查看項目依賴。視圖比較清晰的描述了,項目依賴了2個包,每一個包又分別依賴了其它的一些包。
➜ myproject2 pipenv graph
Django==2.1.3
- pytz [required: Any, installed: 2018.7]
requests==2.20.1
- certifi [required: >=2017.4.17, installed: 2018.10.15]
- chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
- idna [required: >=2.5,<2.8, installed: 2.7]
- urllib3 [required: >=1.21.1,<1.25, installed: 1.24.1]
複製代碼
重用requirements.txt
文件。在項目目錄下建立requirements.txt
,內容參見上文。
$ pipenv install
複製代碼
pipenv 默認會讀取本地目錄,也可使用**-r**參數指定
requirements.txt
位置。
pipenv 的依賴和 venv 有差別,可能直接導入 venv中的
requirements.txt
有一些問題,能夠直接手工安裝。
pipenv就簡單介紹到這裏,你們能夠看pipenv使用指南。總的來講venv和pipenv各有優點吧,venv原生自帶,簡單方便,比較適合服務器上調試;pipenv,功能強大更適合本地調試。
科學計算領域,python著名的庫pandas,numpy和matplotlib, 而後還有圖像處理和視覺這塊的opencv,以及機器學習的tensorflow安裝比較複雜,在這個領域通常使用anaconda的解決方案,其wiki介紹以下:
Anaconda 是一種Python語言的免費增值開源發行版,用於進行大規模數據處理、預測分析,和科學計算,致力於簡化包的管理和部署。 Anaconda使用軟件包管理系統Conda進行包管理。
我選擇的是anaconda3,使用的iterm2,安裝完成後會有路徑問題,須要在~/.zshrc
中添加:
export PATH="/anaconda3/bin:$PATH" 複製代碼
而後訪問使用下面命令查看anaconda環境。
➜ ~ which conda /anaconda3/bin/conda ➜ ~ conda --version conda 4.5.11 複製代碼
建立虛擬環境,並進入虛擬環境:
conda create --name python36 python=3.6 ➜ ~ source activate python36 (python36) ➜ ~ (python36) ➜ ~ python -V Python 3.6.7 :: Anaconda, Inc. (python36) ➜ ~ source deactivate ➜ ~ 複製代碼
查看conda管理的環境列表:
➜ ~ conda info -e # conda environments: # base * /anaconda3 python36 /anaconda3/envs/python36 複製代碼
Anaconda在我的研發過程當中使用很少,若是想了解更多,能夠看Anaconda 入門安裝教程。
前面介紹的內容,都是在本地進行一些配置,建立各類環境。但是本地就一個,折騰幾回後仍是容易亂,docker這麼強大,咱們也能夠用docker來玩python開發。
首先,咱們編寫hello.py
,代碼以下:
# -*- coding:utf-8 -*- def test(): print "Hello, python, docker" if __name__ == "__main__": test() 複製代碼
而後執行下面命令:
docker run -it --rm --name docker-python2 -v "$PWD":/usr/src/myapp -w /usr/src/myapp python:2.7.16-alpine3.9 python hello.py 複製代碼
命令結果以下:
Unable to find image 'python:2.7.16-alpine3.9' locally 2.7.16-alpine3.9: Pulling from library/python 8e402f1a9c57: Already exists d8cdc394c05b: Pull complete 1e2b4a75cc6b: Pull complete 2fbbf60d928e: Pull complete Digest: sha256:46d6e67d464a2811efe60440248623b14cb6db273fac59631dd8bd9e13a77491 Status: Downloaded newer image for python:2.7.16-alpine3.9 Hello, python, docker 複製代碼
注意,初次執行會進行鏡像文件下載,比較緩慢,下載成功後再次執行腳本就會很是迅速了。
這裏的docker命令比較複雜,能夠先不用管它的含義。咱們繼續編寫hello3.py
,代碼以下:
# -*- coding:utf-8 -*- def test(): print("Hello, python, docker") if __name__ == "__main__": test() 複製代碼
使用下面命令執行:
docker run -it --rm --name docker-python3 -v "$PWD":/usr/src/myapp -w /usr/src/myapp python:3.7.3-alpine3.9 python hello3.py 複製代碼
執行結果以下:
Unable to find image 'python:3.7.3-alpine3.9' locally 3.7.3-alpine3.9: Pulling from library/python Digest: sha256:11568bb68bd375727e468ea5995f556139ff305eed9d8ee1d04b1a4a03a6486a Status: Downloaded newer image for python:3.7.3-alpine3.9 Hello, python, docker 複製代碼
咱們簡單瞭解一下運行命令的含義:
➜ python docker run --help Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] -i, --interactive Keep STDIN open even if not attached ... --rm Automatically remove the container when it exits ... -t, --tty Allocate a pseudo-TTY ... -v, --volume list Bind mount a volume --volume-driver string Optional volume driver for the container --volumes-from list Mount volumes from the specified container(s) -w, --workdir string Working directory inside the container 複製代碼
docker run -it --rm --name docker-python2 -v "$PWD":/usr/src/myapp -w /usr/src/myapp python:2.7.16-alpine3.9 python hello.py
翻譯過來的意思大概是下面幾點:
/usr/src/myapp
目錄進行映射。/usr/src/myapp
爲工做目錄,而後運行python hello.py
命令。這樣通過上面幾步,咱們就使用docker容器執行了hello.py
了。並且咱們也有了2個鏡像,能夠分別執行python2和python3的代碼。固然實際的工程中,只是執行一個py文件 有點殺雞用牛刀的感受,能夠若是執行一個django項目,倒是能夠很好的保持開發環境和部署環境的一致。這部份內容,之後我會進行補充介紹。
提示:docker和venv/pipenv也能夠配合使用,將虛擬環境建立在當前目錄便可,留給你們動手探索吧。
最後,咱們一塊兒來簡單回顧一下python虛擬環境:
若是繼續使用pyhon2,能夠參靠下面部份內容。python2的虛擬環境 virtualenv&virtualenvwrapper。
virtualenv 是一個建立隔絕的Python環境的工具,能夠建立一個包含全部必要的可執行文件的文件夾,用來使用Python工程所需的包。
virtualenv安裝很是簡單,直接使用下面命令:
pip install virtualenv
複製代碼
可能會遇到權限問題,可使用sudo提權
可是virtualenv有一個弊端是,每次會在當前目錄建立venv)(pycharm默認使用這種方式),每次須要本身記住不一樣的虛擬機目錄,使用起來不太方便。 這裏咱們直接跳過virtualenv的使用,繼續使用其擴展包virtualenvwrapper
virtualenvwrapper安裝也很是簡單,直接使用下面命令:
pip install virtualenvwrapper
複製代碼
! 注意:windows用戶使用的命令是 pip install virtualenvwrapper-win 後面帶**-win**
使用virtualenvwrapper須要先設置環境變量,我使用的iTerm2
配置的zshrc
,須要在用戶根目錄下的.zshrc
中增長下面2行:
export WORKON_HOME=~/codes/venv source /usr/local/bin/virtualenvwrapper.sh 複製代碼
配置好環境變量後,退出重啓term
生效。
建立一個flask開發環境
mkvirtualenv flask Using base prefix '/Library/Frameworks/Python.framework/Versions/2.7' New python executable in /Users/tu/codes/venv/flask/bin/python Also creating executable in /Users/tu/codes/venv/flask/bin/python Installing setuptools, pip, wheel...done. virtualenvwrapper.user_scripts creating /Users/tu/codes/venv/flask/bin/predeactivate virtualenvwrapper.user_scripts creating /Users/tu/codes/venv/flask/bin/postdeactivate virtualenvwrapper.user_scripts creating /Users/tu/codes/venv/flask/bin/preactivate virtualenvwrapper.user_scripts creating /Users/tu/codes/venv/flask/bin/postactivate virtualenvwrapper.user_scripts creating /Users/tu/codes/venv/flask/bin/get_env_details (flask) ➜ pytest 複製代碼
注意建立好虛擬環境後會自動進入該環境,命令提示符前會顯示當前環境的名稱,例如(flask) 字樣。
再建立一個爬蟲的開發環境
mkvirtualenv spider
...
複製代碼
這樣你能夠在flask的環境中安裝flask庫,spider的環境中安裝requests庫,而不用擔憂依賴衝突。
若是你但願建立一個python3版本的環境,須要先行安裝好python3,而後使用下面命令:
# -p 參數指定版本,可使用python3的絕對路徑 mkvirtualenv py3studio -p python3 複製代碼
其它經常使用命令,以下:
# 列出env列表 workon # 進入指定的env workon name # 退出當前env deactivate # 刪除env rmvirtualenv name 複製代碼
ok,咱們使用pip安裝virtualenv和virtualenvwrapper,順利的解決了不一樣版本的python問題,能夠愉快的開發(玩耍)了。