inspect — 檢測 Python 物件內容
用 inspect 檢查物件的形態
>>> import inspect
>>> inspect.ismodule(inspect) # 檢查 inspect 是否為模組
True
>>> inspect.ismethod(inspect) # 檢查 inspect 是否為物件方法
False
>>> inspect.isfunction(len) # 檢查 len 是否為函式
True
>>> inspect.isbuiltin(len) # 檢查 len 是否為內建函式
True
>>> inspect.isawaitable(inspect) # 檢查 inspect 是否可用於 await expression
False
>>>
透過 inspect 取得物件內的資訊,例如說物件的 docstring、comment 甚至是 source code:
>>> inspect.getdoc(len) # 取得 len 的 docstring
'Return the number of items in a container.'
>>> inspect.getsource(inspect) # 取得 inspect 的 source code
'"""Get useful information from live Python objects.\n\n
This module encapsulates the interface provided by the
internal special\nattributes (co_*, im_*, tb_*, etc.) in ...'
>>>
透過 inspect.getmembers,我們能夠取得一個物件裏面全部的 member:
>>> inspect.getmembers(len)
[('__call__',
<method-wrapper '__call__' of builtin_function_or_method object at 0x7f85af1491c0>),
('__class__', <class 'builtin_function_or_method'>),
('__delattr__',
...,
('__setattr__',
<method-wrapper '__setattr__' of builtin_function_or_method object at 0x7f85af1491c0>),
('__sizeof__',
<built-in method __sizeof__ of builtin_function_or_method object at 0x7f85af1491c0>),
('__str__',
<method-wrapper '__str__' of builtin_function_or_method object at 0x7f85af1491c0>),
('__subclasshook__',
<built-in method __subclasshook__ of type object at 0x899760>),
('__text_signature__', '($module, obj, /)')]
>>> import tabnanny
>>> inspect.getmembers(tabnanny, inspect.isfunction) # get only function
[('check', <function check at 0x7f85acbccbd8>),
('errprint', <function errprint at 0x7f85acbcca68>),
('format_witnesses', <function format_witnesses at 0x7f85acbccf70>),
('main', <function main at 0x7f85acbccb20>),
('process_tokens', <function process_tokens at 0x7f85acb57560>)]
inspect.signature,能夠獲得 callable 的 Signature 物件
>>> def foo(name, a: int, b: float):
... pass
...
>>> sig = inspect.signature(foo)
>>> sig
<Signature (name, a:int, b:float)>
>>> str(sig)
'(name, a:int, b:float)'
>>> sig.parameters
mappingproxy(OrderedDict([('name', <Parameter "name">), ('a', <Parameter "a:int">), ('b', <Parameter "b:float">)]))
透過 Signature.bind,我們能夠把參數給綁定到 signature 上:
>>> args = ('foobar', 10)
>>> kwargs = {'b': 23.4}
>>> bound = sig.bind(*args, **kwargs) # bind args to signature parameters
>>> bound
<BoundArguments (name='foobar', a=10, b=23.4)>
>>> bound.arguments['name']
'foobar'
>>> bound.arguments['a']
10
>>> bound.arguments['b']
23.4