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, 维基百科