跳到内容

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

链接

[编辑 | 编辑源代码]
华夏公益教科书