[Udemy] Python 3: Deep Dive 系列課程備忘錄
Part 1 - Functional
Section 6
影片編號:85
- dir([object]):查詢物件屬性
- inspect module
影片編號:90、91
-
functools.reduce(function, iterable[, initializer])
-
min(iterable), max(iterable), sum(iterable), any(iterable), all(iterable)
- 把遞迴改寫成 reduce:程式碼在影片 #91 時間 18:29 處
影片編號:92
-
functools.partial(func, /, *args, **keywords)
回傳某些參數已經被固定了的 func -
可能的坑:呼叫「某些參數已經被固定了的 func」時,仍可以覆寫被固定住的參數值
def power(base, exponent):
return base ** exponent
square = partial(power, exponent=2)
print(square(5, exponent=3))
影片編號:93
- partial 可能的應用場合: sorted(iterable, *, key=None, reverse=False)、list.sort(*, key=None, reverse=False) 的 key 只能放一個參數的函式
影片編號:94
- operator module:getitem(a, b)、 itemgetter(item)、attrgetter(attr)
Section 7
影片編號:97
- 宣告 global 變數
- when python encounters a function definition at compilt-time
- when function is called at run-time
-
def func4():
print(a)
a = 100
when call func4(),print(a)
result in a run-time error:未賦值的 local 變數
影片編號:98
- 無論是在幾層的巢狀函數中宣告 global 變數,該 global 變數的指到的都是 build-in scop 之下的那層 global scope
x = 0
def func1():
def func2():
global x
x = 5
func2()
print(x) # 0
func1()
print(x) # 5
- 離開 for 迴圈後,變數 x 依然存在
for i in rang(10):
x = 2 * i
print(x)
影片編號:99
- local scope、nonlocal、enclosing scope
- 宣告 nonlocal 變數:只會沿著 enclosing local scopes chain(不含 global scope)去找第一個遇到的同名變數。(影片 10:32 處)
影片編號:100
- 只會沿著 enclosing local scopes chain(不含 global scope)去找第一個遇到的同名變數:所謂的「不含 global scope」,意思是,如果在 enclosing local scopes chain 內宣告 global 變數,這個 golbal 變數不會被算在尋找的對象之內。(影片 12:41 、14:51 處)
影片編號:103
- 用閉包取代 class (程式碼在影片 09:41 處)
影片編號:104
- 用閉包儲存資訊或快取。範例:計算一個函式被呼叫了幾次
影片編號:105
- decorator 的原理:把影片 104 的例子改寫成 decorated function
- 問題:
decorated function 的 __name__ 屬性、help(decorated function)、inspect.signature 會變成 decorator 裡的 inner function 的資訊
解決方式:- __name__ 和 __doc__ 屬性:在 decorator 裡覆寫這兩個屬性(影片 16:17 處)
- __name__ 、 __doc__ 、inspect.signature:用 functools.wraps(影片 18:46 處)
影片編號:107
- 在 decorator 中 import 模組,以免運行環境中沒有 import 該模組
- time.perf_counter() → float
- list 產生規則: F0 = 1, F1 = 1, Fn = Fn-1 + Fn-2。用 decorator 比較三種「產生 list」的方式的速度。三種方式分別為 recursion、loop、reduce
影片編號:108
- datetime.now、timezone.utc
- 兩層 decorator 的執行順序(影片 10:17 處)
- 「沒有權限的人,end point 操作失敗」的 log(影片 20:00 處):留意 decorator 的順序,才能印出想要的 log。
影片編號:108
- 可以用 decorator 改變函式的行為,例如快取(影片 10:33 處)
- @functools.lru_cache(user_function):限制最多快取幾筆資料(影片 23:00 處)
影片編號:110
- 解説可以輸入參數的 decorator:(前情提要影片 3:29 處)(方法一影片 4:45 處)(方法二 decorator factory 影片 7:30 處)
影片編號:111
- 實作可以輸入參數的 decorator:(方法一影片 8:50 處)(方法二 decorator factory 影片 10:40 處)
影片編號:112
- 用 class、__call__ 實作 decorator factory
影片編號:113
- Monkey Patch
- 用 decorator 幫 class 加上新的 method,例如產生 debug message
- vars([object])
- 18:00 處: decorator 沒有 return class 的話會發生什麼事
- 存取 class 中的 private attributes(只是約定上的,實際上依然是 public):@porperty
- NotImplemented
- 寫好了 __eq__、__lt__ (== 和 <)以後,用 decorator 自動產生 __le__、__gt__、__ge__、__ne__(≤、>、≥、≠)(影片 36:00 處)
- @functools.total_ordering(影片 46:00 處)
影片編號:114
- html.escape(s, quote=True)
- htmlize 函式 dispatch 「產生 html 標籤」的任務:依照參數的 type,對參數使用不同的處理方式
- 問題:list 中的項目只有用 html.escape 處理,而不是根據項目的 type 進行相應的處理。解決方法:遞迴(影片 20:55 處)
- 問題:依目前的實作方式,若要讓 htmlize 函式能夠處理新的參數 type,需要先定義新的處理函式,然後在 htmlize 裡面新增「if 某某狀況: 使用新的函式」。解決方法第一步:用 dictionary 紀錄哪個 type 使用哪個函式處理(影片 30:00 處)。解決方法第二步:用 closure 和 decorator,讓我們能在 htmlize 函式外部更新 dictionary 的內容:見影片編號 115
影片編號:115
- (承影片編號:114)解決方法第二步:用 closure 和 decorator,讓我們能在 htmlize 函式外部更新 dictionary 的內容(解說在影片 10:48 處,程式碼在 16:14 處)。查詢某個 type 會用什麼處理方式(程式碼在影片 26:14 處)
- 問題:type 和 isinstance 回傳的結果不一樣:
from collections.abc import Sequence
print(type([1, 2, 3]) is Sequence) # False
print(isinstance([1, 2, 3], Sequence)) # True
Section 8
影片編號:118
- Heterogeneous:item 沒有同樣的 type
- Homogeneous:每個 item 都是同樣的 type
- Dummy variable when unpacking a tuple:習慣上, _ 意味著 ignored variable
city, _, population = ('Beijing', 'China', 21_000_000) # 忽略一個變數
record = ('DJIA', 2018, 1, 19, 25987.35, 26071.72, 25942.83, 26071.72)
symbol, year, month, day, *_, close = record # 忽略連續數個變數
影片編號:119
- tuple is immutable, but if items in a tuple is mutable
- coding style
cities = [('London', 'UK', 8_780_000),
('New York', 'USA', 8_500_000),
('Beijing', 'China', 21_000_000)]
# 計算人口總數
# 方法一
total = 0
for city in cities:
total += city[2]
# 方法二
total = sum(city[2] for city in cities)
影片編號:120
- 為了增加易讀性,把 tuple 中的位置命名: collections.namedtuple(影片 9:25)
- _fields:查詢有哪些 name
- _asdict():將 name - value 轉成 dictionary
Section 9
影片編號:129
- globals():列出當前的 global 變數
- locals():列出當前的 local 變數
- sys.modules:列出已載入的模組
- object.__dict__:列出物件的屬性
- class types.ModuleType(name, doc=None)
- getattr(object, name[, default])取得物件的屬性值
影片編號:130
- Where is python install? sys.prefix
- Where are the compiled C binaries located? sys.exec_prefix
- Where dose Python look for imports? sys.path
影片編號:131
Part 2 - Iteration, Generators
Section
影片編號:
Part 3 - Hash Maps
Section
影片編號:
Part 4 - OOP
Section 2: Classes
影片編號:5.Objects and Classes - Coding
type(MyClass) # type
type(type) # type
type(str) # typetype(MyClass) is MyClass.__class__ # True
isinstance(class_instance, MyClass)
影片編號:6. Class Attributes - Lecture
查詢某個 object 的某屬性的值(class 也是一種 object):
getattr(object, attribute_name: str [, default])
If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.用 dot notation,若 object 沒有該屬性,不能設定回傳的預設值,會直接 AttributeError
setsttr(object, attribute_name, attribute_value)
。python 是動態語言,如果屬性不存在,會建立該屬性。class 是 mutable查詢 class 的 state(class namespace)儲存在 mappingproxy object 裡(不是 dictionary,但是他有 hash map,hash map 是 dictionary) 裡:
MyClass.__dict__
刪除屬性:
delattr(object, attribute_name: str)
del MyClass.attribute_name
影片編號:7. Class Attributes - Coding
MyClass.__dict__ 裡列出來的,不是全部的屬性。例如:__name__ 不在裡面。
因為是 mappingproxy object ,所以不能直接修改 MyClass.__dict__,會 TypeError
mappingproxy object 跟 dictionary 有點像,所以一些 dictionary 的方法也可以使用。例如:
MyClass.__dict__['attribute_name'] # 不建議使用這個方式存取屬性,因為有些屬性無法用這個方式取得
list(MyClass.__dict__.item())
最後更新日期: 2021 年 8 月 17 日
Comments
Post a Comment