Python对象自省——运行时判断对象的类型
简介
自省(introspection)指在运行时判断一个对象的类型
Python中一切都是对象,自省是Python的强项
通过自省可以知道一个对象的能力、状态
type()
type()
返回对象类型
a = list()
print(type(a))
# <class 'list'>
dir()
dir()
是自省的一个重要函数,返回列表,列出对象所拥有的属性和方法
a = list()
print(dir(a))
# ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__',
# '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',
# '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__',
# '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__',
# '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__',
# '__setitem__', '__sizeof__', '__str__', '__subclasshook__',
# 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
pdir()
直接用dir()
看上去非常杂乱,使用pdir()
可以美化输出
安装
pip install pdir2
- 1
代码
import pdir
a = list()
print(pdir(a))
inspect模块
Python标准库中的inspect模块用于获取对象的信息,主要的功能有:
- 类型检查
- 获取源码
- 检查类与函数
- 检查解释器调用堆栈
查看该模块的函数及其含义:
import pdir
import inspect
print(pdir(inspect))
'''
property:
......
module attribute:
......
special attribute:
......
class:
......
function:
......
getmembers: Return all members of an object as (name, value) pairs sorted by name.
getdoc: Get the documentation string for an object.
getmodule: Return the module an object was defined in, or None if not found.
getfile: Work out which source or compiled file an object was defined in.
getsourcefile: Return the filename that can be used to locate an object's source.
getsource: Return the text of the source code for an object.
signature: Get a signature object for the passed callable.
getclasstree: Arrange the given list of classes into a hierarchy of nested lists.
getfullargspec: Get the names and default values of a callable object's parameters.
formatargspec: Format an argument spec from the values returned by getfullargspec.
getcallargs: Get the mapping of arguments to values.
getattr_static: Retrieve attributes without triggering dynamic lookup via the
......
exception:
EndOfBlock: Common base class for all non-exit exceptions.
'''
getmembers() 返回对象成员信息
getmembers()
以键值对列表的形式返回对象所有成员信息
is开头的函数名可作为 getmembers()
的第2个参数
from inspect import *
a = [1, 2, 3]
print(getmembers(a))
print(getmembers(a, isclass)) # 返回类型
print(getmembers(a, isbuiltin)) # 返回内置函数
# [('__add__', <method-wrapper '__add__' of list object at 0x0000000009F9BA88>), ('__class__', <class 'list'>), ('__contains__', <method-wrapper '__contains__' of list object at 0x0000000009F9BA88>), ('__delattr__', <method-wrapper '__delattr__' of list object at 0x0000000009F9BA88>), ('__delitem__', <method-wrapper '__delitem__' of list object at 0x0000000009F9BA88>), ('__dir__', <built-in method __dir__ of list object at 0x0000000009F9BA88>), ('__doc__', "list() -> new empty list\nlist(iterable) -> new list initialized from iterable's items"), ('__eq__', <method-wrapper '__eq__' of list object at 0x0000000009F9BA88>), ('__format__', <built-in method __format__ of list object at 0x0000000009F9BA88>), ('__ge__', <method-wrapper '__ge__' of list object at 0x0000000009F9BA88>), ('__getattribute__', <method-wrapper '__getattribute__' of list object at 0x0000000009F9BA88>), ('__getitem__', <built-in method __getitem__ of list object at 0x0000000009F9BA88>), ('__gt__', <method-wrapper '__gt__' of list object at 0x0000000009F9BA88>), ('__hash__', None), ('__iadd__', <method-wrapper '__iadd__' of list object at 0x0000000009F9BA88>), ('__imul__', <method-wrapper '__imul__' of list object at 0x0000000009F9BA88>), ('__init__', <method-wrapper '__init__' of list object at 0x0000000009F9BA88>), ('__init_subclass__', <built-in method __init_subclass__ of type object at 0x000000006B869530>), ('__iter__', <method-wrapper '__iter__' of list object at 0x0000000009F9BA88>), ('__le__', <method-wrapper '__le__' of list object at 0x0000000009F9BA88>), ('__len__', <method-wrapper '__len__' of list object at 0x0000000009F9BA88>), ('__lt__', <method-wrapper '__lt__' of list object at 0x0000000009F9BA88>), ('__mul__', <method-wrapper '__mul__' of list object at 0x0000000009F9BA88>), ('__ne__', <method-wrapper '__ne__' of list object at 0x0000000009F9BA88>), ('__new__', <built-in method __new__ of type object at 0x000000006B869530>), ('__reduce__', <built-in method __reduce__ of list object at 0x0000000009F9BA88>), ('__reduce_ex__', <built-in method __reduce_ex__ of list object at 0x0000000009F9BA88>), ('__repr__', <method-wrapper '__repr__' of list object at 0x0000000009F9BA88>), ('__reversed__', <built-in method __reversed__ of list object at 0x0000000009F9BA88>), ('__rmul__', <method-wrapper '__rmul__' of list object at 0x0000000009F9BA88>), ('__setattr__', <method-wrapper '__setattr__' of list object at 0x0000000009F9BA88>), ('__setitem__', <method-wrapper '__setitem__' of list object at 0x0000000009F9BA88>), ('__sizeof__', <built-in method __sizeof__ of list object at 0x0000000009F9BA88>), ('__str__', <method-wrapper '__str__' of list object at 0x0000000009F9BA88>), ('__subclasshook__', <built-in method __subclasshook__ of type object at 0x000000006B869530>), ('append', <built-in method append of list object at 0x0000000009F9BA88>), ('clear', <built-in method clear of list object at 0x0000000009F9BA88>), ('copy', <built-in method copy of list object at 0x0000000009F9BA88>), ('count', <built-in method count of list object at 0x0000000009F9BA88>), ('extend', <built-in method extend of list object at 0x0000000009F9BA88>), ('index', <built-in method index of list object at 0x0000000009F9BA88>), ('insert', <built-in method insert of list object at 0x0000000009F9BA88>), ('pop', <built-in method pop of list object at 0x0000000009F9BA88>), ('remove', <built-in method remove of list object at 0x0000000009F9BA88>), ('reverse', <built-in method reverse of list object at 0x0000000009F9BA88>), ('sort', <built-in method sort of list object at 0x0000000009F9BA88>)]
# [('__class__', <class 'list'>)]
# [('__dir__', <built-in method __dir__ of list object at 0x0000000009F9BA88>), ('__format__', <built-in method __format__ of list object at 0x0000000009F9BA88>), ('__getitem__', <built-in method __getitem__ of list object at 0x0000000009F9BA88>), ('__init_subclass__', <built-in method __init_subclass__ of type object at 0x000000006B869530>), ('__new__', <built-in method __new__ of type object at 0x000000006B869530>), ('__reduce__', <built-in method __reduce__ of list object at 0x0000000009F9BA88>), ('__reduce_ex__', <built-in method __reduce_ex__ of list object at 0x0000000009F9BA88>), ('__reversed__', <built-in method __reversed__ of list object at 0x0000000009F9BA88>), ('__sizeof__', <built-in method __sizeof__ of list object at 0x0000000009F9BA88>), ('__subclasshook__', <built-in method __subclasshook__ of type object at 0x000000006B869530>), ('append', <built-in method append of list object at 0x0000000009F9BA88>), ('clear', <built-in method clear of list object at 0x0000000009F9BA88>), ('copy', <built-in method copy of list object at 0x0000000009F9BA88>), ('count', <built-in method count of list object at 0x0000000009F9BA88>), ('extend', <built-in method extend of list object at 0x0000000009F9BA88>), ('index', <built-in method index of list object at 0x0000000009F9BA88>), ('insert', <built-in method insert of list object at 0x0000000009F9BA88>), ('pop', <built-in method pop of list object at 0x0000000009F9BA88>), ('remove', <built-in method remove of list object at 0x0000000009F9BA88>), ('reverse', <built-in method reverse of list object at 0x0000000009F9BA88>), ('sort', <built-in method sort of list object at 0x0000000009F9BA88>)]
class T:
def f(self):
pass
print(getmembers(T(), isbuiltin))
print(getmembers(T(), isroutine)) # 返回内置函数,包括用户自定义
# [('__dir__', <built-in method __dir__ of T object at 0x0000000009F90EF0>), ('__format__', <built-in method __format__ of T object at 0x0000000009F90EF0>), ('__init_subclass__', <built-in method __init_subclass__ of type object at 0x0000000009AFDE78>), ('__new__', <built-in method __new__ of type object at 0x000000006B86C5C0>), ('__reduce__', <built-in method __reduce__ of T object at 0x0000000009F90EF0>), ('__reduce_ex__', <built-in method __reduce_ex__ of T object at 0x0000000009F90EF0>), ('__sizeof__', <built-in method __sizeof__ of T object at 0x0000000009F90EF0>), ('__subclasshook__', <built-in method __subclasshook__ of type object at 0x0000000009AFDE78>)]
# [('__dir__', <built-in method __dir__ of T object at 0x0000000009F90EF0>), ('__format__', <built-in method __format__ of T object at 0x0000000009F90EF0>), ('__init_subclass__', <built-in method __init_subclass__ of type object at 0x0000000009AFDE78>), ('__new__', <built-in method __new__ of type object at 0x000000006B86C5C0>), ('__reduce__', <built-in method __reduce__ of T object at 0x0000000009F90EF0>), ('__reduce_ex__', <built-in method __reduce_ex__ of T object at 0x0000000009F90EF0>), ('__sizeof__', <built-in method __sizeof__ of T object at 0x0000000009F90EF0>), ('__subclasshook__', <built-in method __subclasshook__ of type object at 0x0000000009AFDE78>), ('f', <bound method T.f of <__main__.T object at 0x0000000009F90EF0>>)]
获取源码
getdoc()
:获取文档
getmodule()
:获取所属模块
getfile()
:获取定义对象的文件的名称
getsourcefile()
:获取定义对象的源文件
getsource()
:获取源代码
import requests
from inspect import *
from collections import defaultdict
a = [1, 2, 3]
print(getdoc(list)) # list初始化的文档
print(getdoc(list.append)) # list.append()的文档
# list() -> new empty list
# list(iterable) -> new list initialized from iterable's items
# L.append(object) -> None -- append object to end
print(getmodule(defaultdict)) # 所属模块
# <module 'collections' from 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\collections\\__init__.py'>
print(getfile(requests)) # 定义对象的文件的名称
print(getsourcefile(requests)) # 定义对象的源文件
# C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\requests\__init__.py
# C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\requests\__init__.py
def f():
print('Hello World!')
print(getsource(f)) # 源代码
# def f():
# print('Hello World!')
利用签名对象自省
使用signature()
构建签名对象进行自省,获取参数列表
更多方法查阅inspect.Signature
from inspect import signature
def foo(a, *, b: int, **kwargs):
pass
sig = signature(foo)
print(sig) # 参数列表
print(sig.parameters['b']) # 参数b的类型
print(sig.parameters['b'].annotation) # 参数b的类型标注
# (a, *, b:int, **kwargs)
# b:int
# <class 'int'>
类与函数
getclasstree()
:返回类的继承关系
from inspect import *
from collections import OrderedDict
d = OrderedDict()
classes = getmembers(d, isclass) # 返回类型
print(classes)
classes = [cls[1] for cls in classes] # 组装
print(classes)
tree = getclasstree(classes) # 返回类的继承关系
print(tree)
# [('__class__', <class 'collections.OrderedDict'>)]
# [<class 'collections.OrderedDict'>]
# [(<class 'dict'>, (<class 'object'>,)), [(<class 'collections.OrderedDict'>, (<class 'dict'>,))]]
getfullargspec()
:获取完整参数信息
from inspect import *
def f(a: int, b: float):
pass
print(formatargspec(*getfullargspec(f)))
# (a: int, b: float)
getcallargs()
:获取调用参数
from inspect import *
def f(a, b=1, *pos, **named):
pass
print(getcallargs(f, 1, 2, 3))
print(getcallargs(f, a=2, x=4))
try:
getcallargs(f)
except Exception as e:
print(e)
# {'a': 1, 'b': 2, 'pos': (3,), 'named': {}}
# {'pos': (), 'named': {'x': 4}, 'a': 2, 'b': 1}
# f() missing 1 required positional argument: 'a'
解释器堆栈
更多内容查阅解释器堆栈
from inspect import *
print(getframeinfo(currentframe()))
# Traceback(filename='D:/code/test/test.py', lineno=4, function='<module>', code_context=['print(getframeinfo(currentframe()))\n'], index=0)
- 1
- 2
- 3
- 4
获取静态属性
import math
from inspect import *
class T:
pi = 3.14
print(getattr_static(T, 'pi'))
print(getattr_static(math, 'pi'))
# 3.14
# 3.141592653589793
参考文献
转载自:https://blog.csdn.net/lly1122334/article/details/106895552