成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

怎樣才算學(xué)會Python?

開發(fā) 后端
你可知道Python其實(shí)只是一個語言標(biāo)準(zhǔn),它的實(shí)現(xiàn)程序不止一個,其中官方的實(shí)現(xiàn)是CPython,還有Jython和IronPython等。不過,CPython作為使用最為廣泛的解釋器當(dāng)然是開發(fā)之首選。

[[237230]]
Python inside the door

Python 實(shí)踐基礎(chǔ)

起源

假如你已經(jīng)有了編程基礎(chǔ),那么學(xué)習(xí)一門新語言的困難點(diǎn)絕對不在語法、語義和風(fēng)格等代碼層面上的,而在于語言范式(OO,F(xiàn)P還是Logic),語言的生態(tài)(如:依賴管理和包發(fā)布等)和工具(編輯器,編譯器或者解釋器)這些方面,請參看如何高效地學(xué)習(xí)編程語言。再假如你已經(jīng)對各類語言范式都有一定的了解,那么***的困難之處就是…細(xì)節(jié),它是魔鬼。

我相信真正擁抱一門新語言,花在工具和語言生態(tài)上的時間一定很多。龐大的社區(qū)利用群體智慧構(gòu)筑的生態(tài)圈充滿了各種零碎的知識點(diǎn),這些知識點(diǎn)可能是前人趟過的陷阱(Common Gotchas),基于局部共識經(jīng)由經(jīng)典項(xiàng)目實(shí)踐過之后的約定(Convention)和慣用法(Idioms),也可能是總結(jié)出的概念模式(Pattern),甚至是審美(Aesthetic)和禪(Zen)或道(Dao)。這些知識點(diǎn)作用到了工具和語言生態(tài)之中,意味著你需要使用合適工具、遵循生態(tài)的玩法才能從中受益。

工具

工欲善其事必先利其器,對于程序員而言,這個器是編輯器…嗎?Emacs, Vim, VS Code or PyCharm?

解釋器

當(dāng)然不是,這個器應(yīng)當(dāng)是讓你能立馬運(yùn)行程序并立刻看到結(jié)果的工具,在Python的上下文中,它是Python的解釋器。一般情況下,我們會選擇***版的解釋器或者編譯器,但是Python有一點(diǎn)點(diǎn)例外,因?yàn)镻ython3和2并不兼容,那么該選擇哪個版本呢?尋找這類問題的答案其實(shí)就是融入Python社區(qū)的過程。幸運(yùn)的是,社區(qū)出版了一本書 The Hitchhiker’s Guide to Python,里面誠懇地給出了建議。所以不出意外,Python3是比較合適的選擇。

因?yàn)镻ython安裝起來很簡單,我們跳過…吧?不過,大俠留步,你可知道Python其實(shí)只是一個語言標(biāo)準(zhǔn),它的實(shí)現(xiàn)程序不止一個,其中官方的實(shí)現(xiàn)是CPython,還有Jython和IronPython等。不過,CPython作為使用最為廣泛的解釋器當(dāng)然是開發(fā)之***。

  1. $ python3 
  2. Python 3.6.5 (default, Jun 17 2018, 12:13:06) 
  3. [GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)] on darwin 
  4. Type "help""copyright""credits" or "license" for more information. 
  5. >>> print("hello world"
  6. hello world 

編輯器

雖然面向REPL編程(Repl-Oriented Programming)是一種比單元測試的反饋速度更快的編程方式,但是在REPL中編寫應(yīng)用程序并不合適,不合適的地方表現(xiàn)在代碼不易組織(分模塊)和代碼沒法記錄(存盤)。所以我們需要可以編輯的源代碼、目錄和其它相關(guān)文件,這個時候就需要挑選趁手的編輯器。

神之編輯器Emacs中內(nèi)置了python-mode,如果已經(jīng)是Emacs用戶,這款編輯器當(dāng)是寫Python的不二之選。編輯器之神的Vim排第二,如果你比較喜歡折騰Vim8.0的插件,或者想自己構(gòu)建NeoVim的話。其它的編輯器,我不知道,不想用。不過PyCharm是Jetbrains家的IDE,靠譜。

有功夫在Terminal中裝一個emacsclient,然后下載一個oh-my-zsh的插件emacsclient,就可以很愉悅地在Terminal中使用Emacs編輯文件了。

  1. $ te hello_world.py # te: aliased to /Users/qianyan/.oh-my-zsh/plugins/emacs/emacsclient.sh -nw 
  2. ""
  3. hello_world.py 
  4. Ctrl+x+c 退出emacs :) 
  5. ""
  6. print("hello world"
  7. $ python3 hello_world.py 
  8. hello world 
  9. $ python3 -m hello_world #注意沒有.py的后綴 
  10. hello world 

生態(tài)

基本工具比較好把握,但是何時選擇什么工具做什么樣的事情就不好拿捏了,而且如何把事情做成Pythonic的模樣也是對經(jīng)驗(yàn)和能力的考驗(yàn)。

如果我們不是編程小白的話,就需要充分利用遷移學(xué)習(xí)的能力了。學(xué)習(xí)的***方法就是解決問題。不得不承認(rèn),在動手實(shí)踐的過程,時間走得是最快的,在同一件事上花的時間越多也就越熟悉。

我們嘗試用Python編寫一個tree命令行(Command-Line Application),顧名思義,打印目錄層級結(jié)構(gòu)的程序,詳細(xì)描述參看這篇命令行中 tree 的多重實(shí)現(xiàn)。

測試模塊

怎么寫測試呢?多年養(yǎng)成的TDD習(xí)慣讓我首先想要了解什么是Python中常用的測試工具。答案不難尋找,unittest是Python內(nèi)置的測試模塊,而pytest是比unittest更簡潔和強(qiáng)大的選擇,所以我選擇后者。

這個程序的測試我使用pytest,但是它并不是所有項(xiàng)目測試的唯一選擇,所以***能局部安裝,尤其是限制在當(dāng)前工程目錄里。搜索查找的結(jié)果是,Python3內(nèi)置的虛擬環(huán)境(Virtual Environment)模塊可以做到這點(diǎn)。

虛擬環(huán)境

在當(dāng)前創(chuàng)建venv目錄(python3 -m venv venv),然后用tree命令查看該目錄的結(jié)構(gòu)。

  1. $ python3 -m venv venv 
  2. $ tree -L 4 venv 
  3. venv 
  4. ├── bin 
  5. │   ├── activate 
  6. │   ├── activate.csh 
  7. │   ├── activate.fish 
  8. │   ├── easy_install 
  9. │   ├── easy_install-3.6 
  10. │   ├── pip 
  11. │   ├── pip3 
  12. │   ├── pip3.6 
  13. │   ├── python -> python3 
  14. │   └── python3 -> /usr/local/bin/python3 
  15. ├── include 
  16. ├── lib 
  17. │   └── python3.6 
  18. │       └── site-packages 
  19. │           ├── __pycache__ 
  20. │           ├── easy_install.py 
  21. │           ├── pip 
  22. │           ├── pip-9.0.3.dist-info 
  23. │           ├── pkg_resources 
  24. │           ├── setuptools 
  25. │           └── setuptools-39.0.1.dist-info 
  26. └── pyvenv.cfg 

進(jìn)入虛擬環(huán)境,然后使用pip3安裝pytest測試模塊,會發(fā)現(xiàn)venv目錄多了些東西。

  1. $  . venv/bin/activate 
  2. venv ❯ pip3 install pytest 
  3. Collecting pytest 
  4. ... 
  5. $ tree -L 4 venv 
  6. venv 
  7. ├── bin 
  8. │   ├── py.test 
  9. │   ├── pytest 
  10. ├── include 
  11. ├── lib 
  12. │   └── python3.6 
  13. │       └── site-packages 
  14. │           ├── __pycache__ 
  15. │           ├── _pytest 
  16. │           ├── atomicwrites-1.1.5.dist-info 
  17. │           ├── attr 
  18. │           ├── attrs-18.1.0.dist-info 
  19. │           ├── more_itertools 
  20. │           ├── more_itertools-4.2.0.dist-info 
  21. │           ├── pluggy 
  22. │           ├── pluggy-0.6.0.dist-info 
  23. │           ├── py 
  24. │           ├── py-1.5.3.dist-info 
  25. │           ├── pytest-3.6.2.dist-info 
  26. │           ├── pytest.py 
  27. │           ├── six-1.11.0.dist-info 
  28. │           └── six.py 

此時,虛擬環(huán)境會在PATH變量中前置./bin目錄,所以可以直接使用pytest命令進(jìn)行測試。根據(jù)約定,測試文件的名稱必須以test_開頭,如test_pytree.py,測試方法也必須如此,如test_fix_me。遵循約定編寫一個注定失敗的測試如下:

  1. ""
  2. test_pytree.py 
  3. ""
  4. def test_fix_me(): 
  5.     assert 1 == 0 
  6. $ pytest 
  7. ... 
  8.     def test_fix_me(): 
  9. >       assert 1 == 0 
  10. E       assert 1 == 0 
  11. test_pytree.py:5: AssertionError 

測試失敗了,說明測試工具的打開方式是正確的。在進(jìn)入測試、實(shí)現(xiàn)和重構(gòu)(紅-綠-黃)的心流狀態(tài)之前,我們需要考慮測試和實(shí)現(xiàn)代碼該放在哪里比較合適。

假設(shè)我們會把pytree作為應(yīng)用程序分發(fā)出去供別人下載使用,那么標(biāo)準(zhǔn)的目錄結(jié)構(gòu)和構(gòu)建腳本是必不可少的,Python自然有自己的一套解決方案。

目錄結(jié)構(gòu)

在Packaging Python Projects的指導(dǎo)下,我們略作調(diào)整,創(chuàng)建和源代碼平級的測試目錄(tests),得到的完整目錄如下:

  1. ├── CHANGES 
  2. ├── LICENSE 
  3. ├── README.md 
  4. ├── docs 
  5. ├── pytree 
  6. │   ├── __init__.py 
  7. │   ├── __version__.py 
  8. │   ├── cli.py 
  9. │   └── core.py 
  10. ├── setup.cfg 
  11. ├── setup.py 
  12. ├── tests 
  13. │   ├── fixtures 
  14. │   └── test_pytree.py 
  15. └── venv 

這樣的目錄結(jié)構(gòu)不僅可以清晰地模塊化,隔離測試和實(shí)現(xiàn),提供使用指導(dǎo)和版本更新記錄,還可以很方便地做到包依賴管理和分發(fā),這得歸功于setup.py,它是Python項(xiàng)目中事實(shí)標(biāo)準(zhǔn)(de facto standard)上的依賴和構(gòu)建腳本,pytree下的setup.py內(nèi)容如下:

  1. # setup.py 
  2. # -*- coding: utf-8 -*- 
  3. from setuptools import setup, find_packages 
  4. from codecs import open 
  5. import os 
  6. here = os.path.abspath(os.path.dirname(__file__)) 
  7. about = {} 
  8. with open(os.path.join(here, 'pytree''__version__.py'), 'r''utf-8'as f: 
  9.     exec(f.read(), about) 
  10.      
  11. with open('README.md'as f: 
  12.     readme = f.read() 
  13. with open('LICENSE'as f: 
  14.     license = f.read() 
  15. setup( 
  16.     name='pytree'
  17.     version=about['__version__'], 
  18.     description='list contents of directories in a tree-like format.'
  19.     long_description=readme, 
  20.     author='Yan Qian'
  21.     author_email='qianyan.lambda@gmail.com'
  22.     url='https://github.com/qianyan/pytree'
  23.     license=license, 
  24.     packages=find_packages(exclude=('tests''docs')), 
  25.     classifiers=( 
  26.         "Programming Language :: Python :: 3"
  27.         "License :: OSI Approved :: MIT License"
  28.         "Operating System :: OS Independent"
  29.     ), 
  30.     setup_requires=['pytest-runner'], 
  31.     tests_require=['pytest'], 
  32.     entry_points = { 
  33.         'console_scripts': [ 
  34.             'pytree = pytree.cli:main' 
  35.         ] 
  36.     }, 
  37.     install_requires=[] 

setup.py能幫助我們解決測試中依賴模塊的問題,這樣我們把pytree作為一個package引入到測試代碼中。

  1. venv ❯ python3 
  2. Python 3.6.5 (default, Jun 17 2018, 12:13:06) 
  3. [GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)] on darwin 
  4. Type "help""copyright""credits" or "license" for more information. 
  5. >>> import sys, pprint 
  6. >>> pprint.pprint(sys.path) 
  7. [''
  8.  '/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python36.zip'
  9.  '/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6'
  10.  '/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload'
  11.  '/Users/qianyan/Projects/personal/public/pytree/venv/lib/python3.6/site-packages'
  12.  '/Users/qianyan/Projects/personal/public/pytree/venv/lib/python3.6/site-packages/docopt-0.6.2-py3.6.egg'
  13.  '/Users/qianyan/Projects/personal/public/pytree'

然后運(yùn)行pytest或者python3 setup.py pytest,此時pytest會把.pytree/tests前置到PATH變量中,驗(yàn)證如下:

  1. # test_pytree.py 
  2. import sys 
  3. def test_path(): 
  4.     assert sys.path == '' 
  5. venv ❯ pytest 
  6. -> AssertionError: assert ['/Users/qianyan/Projects/personal/public/pytree/tests',  
  7. '/Users/qianyan/Projects/personal/public/pytree/venv/bin', ...] == '' 
  8. venv ❯ python3 setup.py pytest 
  9. -> AssertionError: assert ['/Users/qianyan/Projects/personal/public/pytree/tests',  
  10. '/Users/qianyan/Projects/personal/public/pytree', ...] == '' 

這里python3 setup.py pytest可以通過setup.cfg設(shè)置別名(alias):

  1. # setup.cfg 
  2. [aliases] 
  3. test=pytest 

python3 setup.py test的效果和前面的命令等同。

使用TDD的方式實(shí)現(xiàn)了pytree核心的功能(源代碼),然后考慮如何把它變成真正的命令行程序。首先要解決的問題是如何以用戶友好的方式顯示需要哪些傳入?yún)?shù),我們期待pytree -h能提供一些幫助信息,為了不重復(fù)造輪子,挑選現(xiàn)成的Option解析庫比較輕松。Python內(nèi)置的argparse已經(jīng)足夠用了,不過docopt值得嘗試。

依賴管理

setup.py提供了依賴管理功能,聲明依賴及其版本號。

  1. # setup.py 
  2. ... 
  3. install_requires=[docopt==0.6.2] 

然后運(yùn)行python3 setup.py develop安裝。就緒之后,編寫cli.py作為命令行程序的入口。

  1. #!/usr/bin env python3 
  2. """list contents of directories in a tree-like format. 
  3.   Usage:  
  4.     pytree <dir> 
  5.     pytree -h | --help | --version 
  6. ""
  7. import pytree.core as pytree 
  8. import pytree.__version__ as version 
  9. def main(): 
  10.     from docopt import docopt 
  11.     arguments = docopt(__doc__, version=version.__version__) 
  12.     dir_name = arguments['<dir>']  
  13.     print('\n'.join(pytree.render_tree(pytree.tree_format('', dir_name)))) 
  14. if __name__ == "__main__"
  15.     main() 

通過打印help信息的方式驗(yàn)證是否符合預(yù)期:

  1. $ python3 pytree/cli.py --help 
  2. list contents of directories in a tree-like format. 
  3.   Usage: 
  4.     pytree <dir> 
  5.     pytree -h | --help | --version 

當(dāng)然理想的結(jié)果是直接可以運(yùn)行pytree --help,setup.py的console_scripts剛好派上用場。

  1. # setup.py 
  2.     entry_points = { 
  3.         'console_scripts': [ 
  4.             'pytree = pytree.cli:main' #以pytree作為命令行程序的調(diào)用名 
  5.         ] 
  6.     } 

此時查看which pytree顯示/Users/qianyan/Projects/personal/public/pytree/venv/bin/pytree,說明pytree已經(jīng)在路徑變量當(dāng)中,可以直接執(zhí)行:

  1. $ pytree tests/fixtures 
  2. tests/fixtures 
  3. └── child 

完成了命令行程序并通過測試,我們嘗試發(fā)布到測試倉庫(TestPyPI)供其他人下載使用。

包發(fā)布

依照文檔描述,先去TestPyPI注冊用戶,本地打包成發(fā)行版,然后安裝twine工具發(fā)布。

  1. $ python3 -m pip install --upgrade setuptools wheel 
  2. $ python3 setup.py sdist bdist_wheel 
  3. $ pytree dist # pytree查看dist目錄 
  4. dist 
  5. ├── pytree-1.0.2-py3-none-any.whl 
  6. └── pytree-1.0.2.tar.gz 
  7. $ python3 -m pip install --upgrade twine 
  8. $ twine upload --repository-url https://test.pypi.org/legacy/ dist/* #or twine upload --repository testpypi dist/* 如果你配置了~/.pypirc 

上傳成功需要一段時間,等待服務(wù)完成同步才可以下載,我們在另一個虛擬環(huán)境中進(jìn)行驗(yàn)證:

  1. $ python3 -m venv test 
  2. $ . test/bin/activate 
  3. test > python3 -m pip install --index-url https://test.pypi.org/simple/ pytree==1.0.2 
  4. test > ls venv/lib/python3.6/site-packages/ 
  5. ... 
  6. pytree 
  7. pytree-1.0.2.dist-info 
  8. ... 

確保site-packages目錄下有這兩個目錄:pytree和pytree-1.0.2.dist-info,然后我們就可以完成***的驗(yàn)證階段了,如下:

  1. test > pytree tests/fixtures 
  2. tests/fixtures 
  3. └── child 

這里版本號之所以是1.0.2,是因?yàn)橐呀?jīng)上傳過了0.0.1, 1.0.0, 1.0.1 等版本,TestPyPI不允許同名同版本的文件重復(fù)上傳,即使刪除原來的文件也不行。前面的版本都有一定的錯誤,錯誤的根因在于find_packages以及package_dir的配置項(xiàng)文檔說明很模糊,而且只有到上傳到TestPyPI然后下載下來,才能驗(yàn)證出來,這種緩慢的反饋是Python的應(yīng)該詬病的地方。

注意

find_package()也是一個深坑,***個參數(shù)如果寫成find_packages('pytree', exclude=...),那么pytree下的所有Python文件都會被忽略。原因是pytree已經(jīng)是package,所以不應(yīng)該讓setup去這個目錄找其他的packages.

這個package_dir也是如此,我們?nèi)绻O(shè)置package_dir={'': 'pytree'},setup.py就會將/Users/qianyan/Projects/personal/public/pytree/pytree前置到PATH中,這會導(dǎo)致console_scripts': ['pytree = pytree.cli:main']拋出錯誤 ModuleNotFoundError: no module named ‘pytree’,究其原因是pytree/pytree導(dǎo)致setup嘗試在pytree/pytree這個package里頭找自己(pytree),自然找不到。但是如果改成console_scripts': ['pytree = cli:main'],因?yàn)閏li在pytree/pytree底下,所以就能成功執(zhí)行。當(dāng)然這是一種錯誤的寫法。

如果遇到了 ModuleNotFoundError: no module named ‘pytree’ 的錯誤,***的方式就是import sys, pprint然后pprint.pprint(sys.path),很容易發(fā)現(xiàn)Python運(yùn)行時的執(zhí)行路徑,這有助于排查潛在的配置錯誤。

責(zé)任編輯:未麗燕 來源: lambeta.com
相關(guān)推薦

2010-11-04 10:55:24

編程語言

2017-05-10 08:39:34

裝機(jī)線纜機(jī)箱

2019-08-01 07:40:01

物聯(lián)網(wǎng)測試物聯(lián)網(wǎng)IOT

2018-03-15 08:36:07

2015-07-29 09:58:29

快速學(xué)習(xí)

2012-10-18 15:07:12

創(chuàng)業(yè)用戶創(chuàng)業(yè)者

2017-12-07 16:13:18

程序員編程代碼

2017-08-14 14:36:02

云計算云服務(wù)云端

2020-12-04 08:24:34

監(jiān)控多維度立體化監(jiān)控系統(tǒng)

2014-06-09 10:51:59

2015-08-17 11:33:58

2012-08-23 09:35:46

2010-01-12 16:55:40

交換機(jī)怎樣設(shè)置

2010-02-02 18:02:20

Python源文件

2010-02-01 14:14:16

安裝Python

2022-08-22 12:03:25

代碼技術(shù)

2025-02-05 08:00:39

2010-02-02 17:18:16

Python圖像處理

2017-12-11 18:11:02

2020-10-08 15:11:45

物聯(lián)網(wǎng)智能家居商業(yè)模式
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 毛片入口 | 欧洲一区二区视频 | 免费久久久久久 | 中文av在线播放 | 国产成人精品久久二区二区91 | 亚洲区一 | 91精品观看| 北条麻妃av一区二区三区 | 午夜小电影 | 91亚洲精选 | 国产精品www | 日韩一级一区 | 久久婷婷av | 亚洲欧美中文字幕在线观看 | 国产一区二区三区 | 视频一区二区在线观看 | 国产精品久久久久久久久久妞妞 | 黄色免费在线观看网站 | 国产区在线免费观看 | 欧美成人精品激情在线观看 | 久久99成人| 国产激情免费视频 | 欧美精品在线免费观看 | 国产精品久久久久久久久久久久 | 久久久久久久久久久久久久久久久久久久 | 男女视频在线观看免费 | 欧美日韩三区 | 69精品久久久久久 | 成人精品一区二区三区中文字幕 | 精品一区电影 | 在线观看亚洲专区 | 久久91精品久久久久久9鸭 | 久久久久久成人 | 欧美日韩国产免费 | 日本精品视频在线观看 | 国产一区二区三区视频免费观看 | 日韩av一区二区在线观看 | 国产精品1区 | 国产一区二区三区在线看 | 国产麻豆乱码精品一区二区三区 | 久草视频在线播放 |