Python 程式設計/反射
外觀
一個 Python 指令碼可以找出物件的型別、類、屬性和方法。這被稱為**反射**或**內省**。另見 元類.
支援反射的函式包括 type()、isinstance()、callable()、dir() 和 getattr()。
type 方法可以用來找出物件的型別。以下測試返回 True
- type(3) is int
- type(3.0) is float
- type(10**10) is long # Python 2
- type(1 + 1j) is complex
- type('Hello') is str
- type([1, 2]) is list
- type([1, [2, 'Hello']]) is list
- type({'city': 'Paris'}) is dict
- type((1,2)) is tuple
- type(set()) is set
- type(frozenset()) is frozenset
- ----
- type(3).__name__ == "int"
- type('Hello').__name__ == "str"
- ----
- import types, re, Tkinter # 以下示例
- type(re) is types.ModuleType
- type(re.sub) is types.FunctionType
- type(Tkinter.Frame) is types.ClassType
- type(Tkinter.Frame).__name__ == "classobj"
- type(Tkinter.Frame()).__name__ == "instance"
- type(re.compile('myregex')).__name__ == "SRE_Pattern"
- type(type(3)) is types.TypeType
type 函式忽略類繼承:"type(3) is object" 返回 False,而 "isinstance(3, object)" 返回 True。
連結
- 2. 內建函式 # type, python.org
- 8.15. types — 內建型別的名稱, python.org
確定一個物件是否是型別或類的例項。
以下測試返回 True
- isinstance(3, int)
- isinstance([1, 2], list)
- isinstance(3, object)
- isinstance([1, 2], object)
- import Tkinter; isinstance(Tkinter.Frame(), Tkinter.Frame)
- import Tkinter; Tkinter.Frame().__class__.__name__ == "Frame"
請注意,isinstance 提供的條件比使用 #Type 的比較更弱。
函式 isinstance 和使用者定義的類
class Plant: pass # Dummy class
class Tree(Plant): pass # Dummy class derived from Plant
tree = Tree() # A new instance of Tree class
print(isinstance(tree, Tree)) # True
print(isinstance(tree, Plant)) # True
print(isinstance(tree, object)) # True
print(type(tree) is Tree) # True
print(type(tree).__name__ == "instance") # False
print(tree.__class__.__name__ == "Tree") # True
連結
- 內建函式 # isinstance, python.org
- isinstance() considered harmful, canonical.org
確定一個類是否為另一個類的子類。與類相關,而不是它們的例項。
class Plant: pass # Dummy class
class Tree(Plant): pass # Dummy class derived from Plant
tree = Tree() # A new instance of Tree class
print(issubclass(Tree, Plant)) # True
print(issubclass(Tree, object)) # False in Python 2
print(issubclass(int, object)) # True
print(issubclass(bool, int)) # True
print(issubclass(int, int)) # True
print(issubclass(tree, Plant)) # Error - tree is not a class
連結
- 內建函式 # issubclass, python.org
鴨子型別提供了一種間接的反射方法。它是一種技術,包括使用一個物件,就好像它是所請求的型別一樣,同時捕獲由於物件不支援類或型別的一些功能而導致的異常。
連結
- Glossary # duck-typing, python.org
對於一個物件,確定它是否可以被呼叫。透過提供一個 __call__() 方法,可以使一個類變得可呼叫。
示例
- callable(2)
- 返回 False。callable("Hello") 和 callable([1, 2]) 也是如此。
- callable([1,2].pop)
- 返回 True,因為 pop 不帶 "()" 返回一個函式物件。
- callable([1,2].pop())
- 返回 False,因為 [1,2].pop() 返回 2 而不是函式物件。
連結
- 內建函式 # callable, python.org
返回物件的屬性名稱列表,其中包括方法。根據 python.org 的說法,它有點啟發式並且可能不完整。
示例
- dir(3)
- dir("Hello")
- dir([1, 2])
- import re; dir(re)
- 列出 re 模組中可用的函式和其他物件的名稱,用於正則表示式。
連結
- 內建函式 # dir, python.org
返回物件的屬性值,該屬性名稱作為字串傳遞。
示例
- getattr(3, "imag")
可以使用 #Dir 獲取物件的屬性列表。
連結
- 內建函式 # getattr, python.org
Python 關鍵字列表可以從 Python 中獲取
import keyword
pykeywords = keyword.kwlist
print(keyword.iskeyword("if")) # True
print(keyword.iskeyword("True")) # False
連結
- 32.6. keyword — 測試 Python 關鍵字, python.org
Python 內建物件和函式列表可以從 Python 中獲取
print(dir(__builtins__)) # Output the list
print(type(__builtins__.list)) # = <type 'type'>
print(type(__builtins__.open)) # = <type 'builtin_function_or_method'>
print(list is __builtins__.list) # True
print(open is __builtins__.open) # True
連結
- 28.3. __builtin__ — 內建物件, python.org
- 內建函式 # dir, python.org
- 2. 內建函式, docs.python.org
- 如何在 Python 中確定變數型別?, stackoverflow.com
- Python 中 isinstance() 和 type() 的區別, stackoverflow.com
- W:Reflection (computer_programming)#Python, 維基百科
- W:Type introspection#Python, 維基百科