我Python 最佳實踐指南

閱讀這份指南我所學到的

1. 代碼風格

pip install pycodestylepycodestyle .pypip install autopep8autopep8 --in-place optparse.py# 不包含 --in-place 標誌將會使得程序直接將更改的代碼輸出到控制台,以供審查。 # --aggressive 標誌則會執行更多實質性的變化,而且可以多次使用以達到更佳的效果my_very_big_string = ( "For a long time I used to go to bed early. Sometimes, " "when I had put out my candle, my eyes would close so quickly " "that I had not even time to say 「I』m going to sleep.」")# 行的延續

2. Python Basics

# 嵌套函數與閉包# 文件讀取與寫入 "a" "w" "r"# yield lambda 函數(即一種匿名函數)# 面向對象編程 (屬性與方法)__init__(self, *arg) # 構造函數__str__(self) #@override return str_namestatic attribute # 定義在 __init__ 函數外 所有類實例共享# 繼承與多態class son(Parent): pass # super().method_name # 調用父類方法# 注釋# Pypi# 調試 (vscode 大法好)# 創建可執行文件 (pyinstaller)# setup 文件 requirements 文件# ansible???# python fg (終端)# / or //# int float NoneType bool# str 在 python 里是 immutable sequences of unicode codepoints# bytes 在 python 里是 immutable sequences of bytes# .encode() .decode()# list 在 python 里是 mutable sequences of objects# dict 在 python 里是 mutable mappings of keys to values# Special attributes in Python are delimited by double underscores"""__name__ gives us the means for our module to detect whether it has been run as a script or imported into another module or the REPL."""print(__name__)if __name__ == __main__: function()# sys.argv[1]# advanced command line argument parsing:# Python Standard Library: argparse# Many third-party options such as docopt# docstrings 的使用方式"""descriptionArgs: description# 可選Raises: IOError: ......Returns: description"""# #! 符號#!/use/bin/env python3# 注意: Module code is executed exactly once, on first import 即上面的 print 函數只會執行一次# value equality vs. identity (使用 is)# 一個容易出錯的地方a = [1, 2]def replace(f): f = [4, 5]replace(a) # 結果: a 的值還是 [1, 2] 這其實還是一種閉包 (closure)# 即 Function arguments are passed by object-reference (使用 id() 可以驗證)# dir() 查看屬性 __name__ __doc__################################################# # Static # Dynamic################################################# Strong # # Python################################################# Weak # # JavaScript#################################################解釋上圖:# 1.In a dynamic type system object types are only resolved at runtime# 2.In a strong type system there is no implicit(隱式)type conversion# 作用域Local Enclosing Global Built-in(LEGB)# 一個容易出錯的地方count = 0def show_count(): print("count = ", count)def set_count(c): global count # 不加這一行會出錯 count = c# Everything is an Object(一切皆對象)# we follow patterns Not to kill complexity But to master it# Special cases arent special enough to break the rules# Python Collections(str/list/dict/tuple/range/set)# 1.tupleheterogeneous(各種各樣的) immutable sequence("www", 123, True) # in or not in# 2. stringhomogeneous(同類的同性質的) immutable sequence of Unicode codepoints(characters).split() .join().partition() # divide a string into three around a seperator:# prefix, separator, suffix# 3. rangearithmetic(算數演算法) progression of integers# 4. Listheterogeneous mutable sequence.index(item) # ValueError if not found.insert(index, item).extend(list).reverse().sort() # reverse=True# built-in functionsorted(list)list(reversed(list))# 5. Dict{}dict([(), ()])dicr(a=b, c=d).copy().update().values() # 忽略 keys.keys() # 同上.items() # 同上from pprint import pprint as pp # pretty print 美化作用# 6. Setunordered collection of unique, immutable objects{1, 4, 67, 8999}s = set([list]).remove().discard().copy().union() # 並集.intersection() # 交集.difference() # 交集的補集.symmetric_difference() # 補集.issubset() # 子集.issuperset() # 父集.isdisjoint() # 不相交# Handle Exception (覺得用不到哎 大部分時候)Rasie/Handle/Unhandled exceptions/Exception objectstry:except ValueError: # except (ValueError, TypeError) as e: # str(e)(finally)return# Indentation Error/ SyntaxError/ NameError# Iterable Objects(可迭代對象)# List/Set/Dict Comprehension(遞推式構造列表)iter() # 獲得 iteratornext() # 獲得當前元素# generator 通關 yeild 生成from itertools import islice, countany()zip()# unittest(單元測試)unittest# debuggingpdb# distribute your program# in the face of ambiguity, refuse the temptation to guess(這句話很有道理)# You can pass -m to your Python command to have it run a module as a script

淺拷貝

3. Python 進階

3.1 Python 包(Package)與模塊(Module)

簡單理解包和模塊的區別是:包是一組模塊的集合# sys.path.append# export PYTHONPATH=path_name# 包的結構reader/__init__.pyreader/reader.pytouch reader/__init__.pyimport readerprint(type(reader))reader.__file__ # 結果: ./reader/__init__.py# 子包(Subpackages)reader/compressed/__init__.pyreader/compressed/bzipped.pyreader/compressed/gzipped.pyimport readerimport reader.compressedimport reader.compressed.bzipped# absoulte imports 和 relative imports# .b (當前路徑下的module)# ..a (上一路徑下的module)from ..a import Afrom . import common# 命名空間包# namespace packages (packages split across several directories)# useful for spliting large packages into multiple parts# namesapce packages have no __init__.py# This avoids complex initialization ordering problems# sys.path.extend([path1, path2])# __main__.py 可執行的文件夾 包 在終端# layoutproject_name/project_name/__main__.pyproject_name/project_name/__init__.pyproject_name/project_name/subpackage/__init__.pyproject_name/project_name/test/__init__.pyproject_name/setup.py

3.2 深入理解 Python 函數

__call__() # 一個 built_in 的函數 理念是 class 可以像 function 一樣被執行# 即 Callable instances# 簡潔表達result = true_value if condition else false_value# lambda 函數callable() # bulit_in 函數 檢測是否可調用# *args **agrs (參數的映射)# extended() (對應展開)t = (11, 12, 13, 14)f(*t)f(arg1, arg2, *arg3)# trace(f, *args, **args)int(ff, base=16) # <=> trace(int, "ff", base=16)# transpose tablestansposed = list(zip(*daily)) # 神奇 cool# local function(區域函數 decorator closure)def sort_by_last_letter(strings): x = clo def last_letter(s): # 每次的區域函數並不相同,沒有 cahe return s[-1] + x return sorted(strings, key=last_letter)sort_by_last_letter.last_letter(s)test = sort_by_last_letter(ert)test.__closure__l# function factory : function that returns new, specialized functions(閉包的應用)def raise_to(exp): def raise_to_exp(x): return pow(x, exp) return rasie_to_exp# LEGB does not apply when making new bindings.# global: introduce names from global namespace into the local namespace# how can you do the same for name bindings in enclosing scopes?(所以有了 nonlocal)# nonlocal: introduce names from the enclosing namespace into the local namespace# cool~ 繼續加油# decorator(裝飾器): modify or enhance fucntions without changing their definition# implemented as callables that take and return other callables# replace, enhance, or modify existing functionsdef escape_unicode(f): def wrap(*args, **kwargs): x = f(*args, **kwargs) return ascii(x) return wrap@escape_unicodedef china_city(): return 西安# 用作裝飾器的對象必須是 callable# class objects as decoratorsclass My_class: def __init__(self, f): self.f = f self.count = 0 def __call__(self, *args, **kwargs): self.count += 1 return self.f(*args, **kwargs)@My_classdef hello(name): print(Hello, {}.format(name))hello.count# class instances as decoratorsclass Trace: def __init__(self): self.enabled = True def __call__(self, f): def wrap(*args, **kwargs): if self.enabled: print(Calling {}.format(f)) return f(*args, **kwargs) return wraptracer = Trace()@tracerdef rolate_list(l): return l[1:] + [l[0]]# 多個裝飾器@tracer@escape_unicodedef china_island_maker(name): return name + # class 里使用裝飾器class IslandMaker: def __init__(self, suffix): self.suffix = suffix @tracer def make_island(self, name) return name + self.suffix# 之前使用裝飾器存在的問題: Naive decorators can lose important metadataimport functools@functools.wraps()# 例子: Validating Argumentsdef check_non_negative(index): def validator(f): def wrap(*args): if args[index] < 0: raise ValueError( Argument {} must be non-negative..format(index)) ) return f(*args) return wrap return validator@check_non_negative(1)def create_list(value, size): return [value] * size

3.3 深入理解 Python 面向對象編程

# class attr(better not) vs. instance attr# static methods with the @staticmethod decorator ()# class methods with the @classmethod decorator (cls)# static methods 的繼承# class methods 的繼承# 沒什麼特別之處 與普通的 methods 繼承方法一樣 (同樣可以 override)# encapsulation(包裝,包裹,封裝) using the @property decorator# 第一次接觸以上概念 道理都懂 什麼時候用啊 可以看懂程序就好 吧?!@property# getter 函數def attr1(self): return self._attr1@attr1.setter# setter 函數def attr1(self, value): self._attr1 = value# 知乎的編輯器難用的更翔一樣# 狗幣知乎 自動保存十分的噁心# Method Resolution Order(mro)# class-bound# instance-bound# (這部分內容有遺失,抽空補上)# 多繼承class subClass(Base1, Base2, ...): pass# method resolution order(MRO) determines name lookup in all casesclassName.__bases__ className.__mro__ (.mro()) # 見下圖# C3 algorithm for calculating MRO in python# super() 感覺這個蠻重要的# super() returns a proxy object which routes method calls# Bound proxy: bound to a specific class or instance (更主要)# Unbound proxy: not bound to a class or instance# 代理綁定分為: instance-bound and class-bound

# 下面 介紹 instance-bound proxysuper(ClassName, self).__init__() <=> super().__init()# 即 look for a method on the base class# 這也是一種實例綁定# calling super without arguments

3.4 深入理解 Python 語言特性

# Exceptions and Errors# Exceptions are arranged in an inheritance hierarchy # assertassert 5 > 2, "This is a error"raise("some words")except ValueError as e: print("payload:", e.args)# chaining exception# __traceback__# Defining Context Managers# an object designed to be used in a with-statement# A context-manager ensures that resources are properly and automatically managed# Python introspection(自省)# 很牛逼的屬性 基本用不到 為什麼用不到 因為你還不夠牛逼

3.5 單元測試(Python 測試)

# 測試很重要 應該了解一下# unittest pytest doctestpython3 -m unittest -v# setup teardown

# pytest# 比 unittest 使用方便不少# 就是導入你想要 test 的類 # 然後定義函數 以及一堆 assert 表達式with pytest.raises(KeyError): className.method(*arg)pytest.skip("")# test fixture (setup 和 teardown)@pytest.fixturedef phonebook(request): phonebook = Phonebook() def cleanup_phonebook(): phonebook.clear() request.add_finalizer(cleanup_phonebook) return phonebook# doctest# test double (目測暫時用不到 跳過)# the coverage and parameterized test(參數化測試)# 1.measuring coverage of tests# 2.using code coverage metrics when adding test cases# using a custom assert to reduce duplicationpip install coveragepip install pytest-covpython3 -m pytest --cov-report term-missing --cov tennispython3 -m pytest --cov-report html --cov tennis

4. Python 應用 (關於 Flask)

# microframework# templates: Jinja 2 / Http and routing: Werkzeug / (Model), View, Controller# Blueprints# Development server + debugger# Unit testing support

5. 總結

# 待續

知識無窮盡

Do something that is important and special for you.

That is the best way for anyone to learn.


推薦閱讀:

Flask實踐:猜數字
Flask實踐:計算器
上雲連載5:使用 Nginx + uWSGI 部署 Flask 應用
flask並發是如何區分用戶的?
flask web 開發一書,第一章的安裝,win10系統為什麼激活不了虛擬環境???

TAG:Python入門 | Python教程 | Flask |