Python 的自省机制经常会在面试中接触到,所谓自省(introspection)其实有点像 Java 或者其他语言中的反射机制(个人见解),主要是方便程序在运行时获取对象的信息。
Python 中一切皆对象我们可以通过自省方法来操作对象的相关属性。
方法 | 作用 |
---|---|
type() | 查看对象的类型 |
dir() | 返回对象的所有属性 |
help() | 查看函数或模块用途的详细说明 |
isinstance() | 判断对象是否是已知类型 |
issubclass() | 判断一个类是否是另一个类的子类 |
id() | 用于获取对象的内存地址 |
callable() | 判断对象是否可以被调用 |
hasattr() | 查看对象是否有特定属性 |
getattr() | 获取对象的特定属性 |
setattr() | 设置对象的特定属性 |
delattr() | 删除对象的特定属性 |
dir() 是一个比较常见的反射函数,它返回传递给它的任何对象的属性名称经过排序的列表。如果不指定对象,则 dir() 返回当前作用域中的名称。
>>> import keyword
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'keyword']
>>> dir(keyword)
['__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'iskeyword', 'kwlist', 'main']
type() 可以帮助我们判断对象的类型。
>>> type(66)
<class 'int'>
>>> type([])
<class 'list'>
isinstance() 函数测试对象以确定它是否是某个特定类型或定制类的实例.
>>> isinstance("hello", str)
True
下面示例代码演示 getattr()、hasattr()、setattr()、delattr() 的使用。
class Demo:
def __init__(self):
self.name = "hello"
def todo(self):
pass
# 实例化
demo = Demo()
# 获取对象中的属性、方法
name = getattr(demo, "name")
func = getattr(demo, "todo")
print(name)
print(func)
# 查看是否有属性或方法
print(hasattr(demo, "name"))
print(hasattr(demo, "todo"))
# 设置对象的属性值
setattr(demo, "name", "aaa") # 已有的属性值会修改
setattr(demo, "age", 10) # 没有该属性会新增并赋值
# 删除对象的属性
delattr(demo, "name")
输出如下:
hello
<bound method Demo.todo of <__main__.Demo object at 0x10c90d7f0>>
True
True
可以通过反射在运行时导包,示例如下。
# 导包
time = __import__('time')
# 获取方法
sleep = getattr(time, "sleep")
# 调用
sleep(1)
功能等价于下面的代码:
import time
time.sleep(5)