跳到內容

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。

連結

Isinstance

[編輯 | 編輯原始碼]

確定一個物件是否是型別或類的例項。

以下測試返回 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

連結

Issubclass

[編輯 | 編輯原始碼]

確定一個類是否為另一個類的子類。與類相關,而不是它們的例項。

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

連結

鴨子型別

[編輯 | 編輯原始碼]

鴨子型別提供了一種間接的反射方法。它是一種技術,包括使用一個物件,就好像它是所請求的型別一樣,同時捕獲由於物件不支援類或型別的一些功能而導致的異常。

連結

可呼叫

[編輯 | 編輯原始碼]

對於一個物件,確定它是否可以被呼叫。透過提供一個 __call__() 方法,可以使一個類變得可呼叫。

示例

  • callable(2)
    • 返回 False。callable("Hello") 和 callable([1, 2]) 也是如此。
  • callable([1,2].pop)
    • 返回 True,因為 pop 不帶 "()" 返回一個函式物件。
  • callable([1,2].pop())
    • 返回 False,因為 [1,2].pop() 返回 2 而不是函式物件。

連結

返回物件的屬性名稱列表,其中包括方法。根據 python.org 的說法,它有點啟發式並且可能不完整。

示例

  • dir(3)
  • dir("Hello")
  • dir([1, 2])
  • import re; dir(re)
    • 列出 re 模組中可用的函式和其他物件的名稱,用於正則表示式。

連結

返回物件的屬性值,該屬性名稱作為字串傳遞。

示例

  • getattr(3, "imag")

可以使用 #Dir 獲取物件的屬性列表。

連結

關鍵字

[編輯 | 編輯原始碼]

Python 關鍵字列表可以從 Python 中獲取

import keyword
pykeywords = keyword.kwlist
print(keyword.iskeyword("if"))     # True
print(keyword.iskeyword("True"))   # False

連結

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

連結

[編輯 | 編輯原始碼]
華夏公益教科書