use inspect module to figure out the attributes in a function object.
there is a clip function below:

def clip(text, max_len=80):
    """    return text clipped at the last space before or after max_len
    """
    end = None
    if len(text) > max_len:
        space_before = text.rfind(' ', 0, max_len)
        if space_before >= 0:
            end = space_before
        else:
            space_after = text.rfind(' ', max_len)
            if space_after >= 0:
                end = space_after
    if end is None:
        end = len(text)
    return text[:end].rstrip()


clip.__defaults__    # return a tuple which contains the default value




(80,)




clip.__code__




<code object clip at 0x0000000003DA89C0, file "<ipython-input-1-90da76271be0>", line 1>




dir(clip.__code__)




['__class__',
 '__delattr__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__le__',
 '__lt__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'co_argcount',
 'co_cellvars',
 'co_code',
 'co_consts',
 'co_filename',
 'co_firstlineno',
 'co_flags',
 'co_freevars',
 'co_kwonlyargcount',
 'co_lnotab',
 'co_name',
 'co_names',
 'co_nlocals',
 'co_stacksize',
 'co_varnames']




clip.__code__.co_argcount # number of arguments




2




clip.__code__.co_varnames # name of variables




('text', 'max_len', 'end', 'space_before', 'space_after')




clip.__code__.co_freevars




()




clip.__code__.co_kwonlyargcount




0




clip.__code__.co_code




b'd\x01\x00}\x02\x00t\x00\x00|\x00\x00\x83\x01\x00|\x01\x00k\x04\x00rl\x00|\x00\x00j\x01\x00d\x02\x00d\x03\x00|\x01\x00\x83\x03\x00}\x03\x00|\x03\x00d\x03\x00k\x05\x00rB\x00|\x03\x00}\x02\x00ql\x00|\x00\x00j\x01\x00d\x02\x00|\x01\x00\x83\x02\x00}\x04\x00|\x04\x00d\x03\x00k\x05\x00rl\x00|\x04\x00}\x02\x00ql\x00n\x00\x00|\x02\x00d\x01\x00k\x08\x00r\x87\x00t\x00\x00|\x00\x00\x83\x01\x00}\x02\x00n\x00\x00|\x00\x00d\x01\x00|\x02\x00\x85\x02\x00\x19j\x02\x00\x83\x00\x00S'




import inspect


sig = inspect.signature(clip)


sig




<inspect.Signature at 0x4748710>




str(sig)




'(text, max_len=80)'




for name,param in sig.parameters.items():
    print("{}:{} = {}".format(name,param.kind,param.default))

text:POSITIONAL_OR_KEYWORD = <class 'inspect._empty'>
max_len:POSITIONAL_OR_KEYWORD = 80

在inspect模块中的_ParameterKind类中,有五种类型的参数:
1.POSITIONAL_OR_KEYWORD
位置参数或关键字参数,绝大部分的函数都具有这一类型的参数。
2.VAR_POSITIONAL
位置参数,这些位置参数形成了tuple
3.VAR_KEYWORD
关键字赋值类型参数,这些参数形成了字典
4.KEYWORD_ONLY
只能是关键字参数,python3中新出现的类型
5.POSITIONAL_ONLY
只能是位置参数。现在的python函数定义语法并不支持这一类型。
但是例外存在于C实现的函数,比如divmod,这个函数不支持关键字函数。

my_tag = {'text': 'img', 'max_len': 80}


bound_args = sig.bind(**my_tag)


bound_args




<inspect.BoundArguments at 0x475cba8>




for name, value in bound_args.arguments.items():
    print("{}={}".format(name, value))

text=img
max_len=80



del my_tag['max_len']


sig.bind(**my_tag) # that's ok the max_len has default value 80




<inspect.BoundArguments at 0x44c3400>




my_tag




{'text': 'img'}




my_tag['max_len'] = 80


del my_tag['text']


sig.bind(**my_tag) # error! need the value of text


---------------------------------------------------------------------------

StopIteration                             Traceback (most recent call last)

C:\Python34\lib\inspect.py in _bind(self, args, kwargs, partial)
   2532             try:
-> 2533                 arg_val = next(arg_vals)
   2534             except StopIteration:


StopIteration: 


During handling of the above exception, another exception occurred:


TypeError                                 Traceback (most recent call last)

<ipython-input-49-1c401fb09162> in <module>()
----> 1 sig.bind(**my_tag)


C:\Python34\lib\inspect.py in bind(*args, **kwargs)
   2650         if the passed arguments can not be bound.
   2651         '''
-> 2652         return args[0]._bind(args[1:], kwargs)
   2653 
   2654     def bind_partial(*args, **kwargs):


C:\Python34\lib\inspect.py in _bind(self, args, kwargs, partial)
   2569                             msg = '{arg!r} parameter lacking default value'
   2570                             msg = msg.format(arg=param.name)
-> 2571                             raise TypeError(msg) from None
   2572             else:
   2573                 # We have a positional argument to process


TypeError: 'text' parameter lacking default value