【Python】【有趣的模块】tqdm | inspect

tqdm

"""

【tqdm】 显示循环的进度条,再也不用担心程序跑到哪里还要跑多久了

tqdm 可以直接包裹iterable对象

from tqdm import tqdm,trange
from time import sleep

text = ""
for char in tqdm(['a','b','c','d']):
text += char
sleep(1)

trange(i)相当于tqdm(range(i))

from tqdm import tqdm,trange
from time import sleep
for i in trange(100):
sleep(0.01)

可以在循环外预先定义tqdm对象

pbar = tqdm(['a','b','c','d','e','f','g','aaa'])
for char in pbar:
pbar.set_description("Processing %s" % char) #Processing aaa: 100%|██████████| 8/8 [00:00<00:00, 14260.28it/s]

'''
有两个参数比较有用,desc(str)和leave(bool)
desc可以指定这个循环的的信息,以便区分。上面的set_description(str)和这个应该是一样的。
leave则表示进度条跑完了之后是否继续保留
'''

from tqdm import tqdm,trange
from time import sleep

for i in tqdm(range(3),desc='1st loop'):
for j in trange(5,desc='2nd loop',leave=False):
sleep(0.1)
'''
leave == True
1st loop: 0%| | 0/3 [00:00<?, ?it/s]
2nd loop: 0%| | 0/5 [00:00<?, ?it/s]
2nd loop: 20%|██ | 1/5 [00:00<00:00, 9.96it/s]
2nd loop: 40%|████ | 2/5 [00:00<00:00, 9.82it/s]
2nd loop: 60%|██████ | 3/5 [00:00<00:00, 9.78it/s]
2nd loop: 80%|████████ | 4/5 [00:00<00:00, 9.76it/s]
2nd loop: 100%|██████████| 5/5 [00:00<00:00, 9.73it/s]
1st loop: 33%|███▎ | 1/3 [00:00<00:01, 1.94it/s]
2nd loop: 0%| | 0/5 [00:00<?, ?it/s]
2nd loop: 20%|██ | 1/5 [00:00<00:00, 9.94it/s]
2nd loop: 40%|████ | 2/5 [00:00<00:00, 9.81it/s]
2nd loop: 60%|██████ | 3/5 [00:00<00:00, 9.78it/s]
2nd loop: 80%|████████ | 4/5 [00:00<00:00, 9.76it/s]
2nd loop: 100%|██████████| 5/5 [00:00<00:00, 9.74it/s]
1st loop: 67%|██████▋ | 2/3 [00:01<00:00, 1.95it/s]
2nd loop: 0%| | 0/5 [00:00<?, ?it/s]
2nd loop: 20%|██ | 1/5 [00:00<00:00, 9.86it/s]
2nd loop: 40%|████ | 2/5 [00:00<00:00, 9.75it/s]
2nd loop: 60%|██████ | 3/5 [00:00<00:00, 9.69it/s]
2nd loop: 80%|████████ | 4/5 [00:00<00:00, 9.67it/s]
2nd loop: 100%|██████████| 5/5 [00:00<00:00, 9.67it/s]
1st loop: 100%|██████████| 3/3 [00:01<00:00, 1.94it/s]
leave == False
1st loop: 0%| | 0/3 [00:00<?, ?it/s]
2nd loop: 0%| | 0/5 [00:00<?, ?it/s]
2nd loop: 20%|██ | 1/5 [00:00<00:00, 9.85it/s]
2nd loop: 40%|████ | 2/5 [00:00<00:00, 9.69it/s]
2nd loop: 60%|██████ | 3/5 [00:00<00:00, 9.63it/s]
2nd loop: 80%|████████ | 4/5 [00:00<00:00, 9.68it/s]
2nd loop: 100%|██████████| 5/5 [00:00<00:00, 9.67it/s]
1st loop: 33%|███▎ | 1/3 [00:00<00:01, 1.93it/s]
2nd loop: 0%| | 0/5 [00:00<?, ?it/s]
2nd loop: 20%|██ | 1/5 [00:00<00:00, 9.55it/s]
2nd loop: 40%|████ | 2/5 [00:00<00:00, 9.69it/s]
2nd loop: 60%|██████ | 3/5 [00:00<00:00, 9.68it/s]
2nd loop: 80%|████████ | 4/5 [00:00<00:00, 9.64it/s]
2nd loop: 100%|██████████| 5/5 [00:00<00:00, 9.68it/s]
1st loop: 67%|██████▋ | 2/3 [00:01<00:00, 1.93it/s]
2nd loop: 0%| | 0/5 [00:00<?, ?it/s]
2nd loop: 20%|██ | 1/5 [00:00<00:00, 9.60it/s]
2nd loop: 40%|████ | 2/5 [00:00<00:00, 9.70it/s]
2nd loop: 60%|██████ | 3/5 [00:00<00:00, 9.68it/s]
2nd loop: 80%|████████ | 4/5 [00:00<00:00, 9.65it/s]
2nd loop: 100%|██████████| 5/5 [00:00<00:00, 9.66it/s]
1st loop: 100%|██████████| 3/3 [00:01<00:00, 1.93it/s]
'''

'''
如果要在Jupyter Notebook上面使用,那么要把tqdm换成tqdm_notebook,trange换成tnrange
在Jupyter Notebook里面没有这个问题,还能用print()。

from tqdm import tnrange, tqdm_notebook
from time import sleep

for i in tqdm_notebook(range(10), desc='1st loop'):
for j in tnrange(100, desc='2nd loop', leave=False):
sleep(0.01)
'''

如果要在终端运行期间打印什么,用tqdm.write(str)

from tqdm import tqdm,trange
from time import sleep

for i in trange(10):
tqdm.write(str(i))
sleep(0.1)
'''
千奇百怪的结果
1⃣️
0
1
2
3
4
5
6
7
8
80%|████████ | 8/10 [00:00<00:00, 9.65it/s]9
90%|█████████ | 9/10 [00:00<00:00, 9.67it/s]100%|██████████| 10/10 [00:01<00:00, 9.66it/s]
2⃣️
0
0%| | 0/10 [00:00<?, ?it/s]1
10%|█ | 1/10 [00:00<00:00, 9.70it/s]2
20%|██ | 2/10 [00:00<00:00, 9.70it/s]3
40%|████ | 4/10 [00:00<00:00, 9.65it/s]4
5
50%|█████ | 5/10 [00:00<00:00, 9.60it/s]6
60%|██████ | 6/10 [00:00<00:00, 9.61it/s]7
70%|███████ | 7/10 [00:00<00:00, 9.60it/s]8
80%|████████ | 8/10 [00:00<00:00, 9.60it/s]9
90%|█████████ | 9/10 [00:00<00:00, 9.62it/s]100%|██████████| 10/10 [00:01<00:00, 9.63it/s]
3⃣️
0
1
10%|█ | 1/10 [00:00<00:00, 9.48it/s]2
30%|███ | 3/10 [00:00<00:00, 9.54it/s]3
4
40%|████ | 4/10 [00:00<00:00, 9.61it/s]5
60%|██████ | 6/10 [00:00<00:00, 9.61it/s]6
7
70%|███████ | 7/10 [00:00<00:00, 9.61it/s]8
80%|████████ | 8/10 [00:00<00:00, 9.60it/s]9
100%|██████████| 10/10 [00:01<00:00, 9.66it/s]
4⃣️
0
10%|█ | 1/10 [00:00<00:00, 9.71it/s]1
2
20%|██ | 2/10 [00:00<00:00, 9.73it/s]3
40%|████ | 4/10 [00:00<00:00, 9.72it/s]4
5
50%|█████ | 5/10 [00:00<00:00, 9.69it/s]6
60%|██████ | 6/10 [00:00<00:00, 9.67it/s]7
80%|████████ | 8/10 [00:00<00:00, 9.67it/s]8
90%|█████████ | 9/10 [00:00<00:00, 9.65it/s]9
100%|██████████| 10/10 [00:01<00:00, 9.64it/s]
5⃣️
0
0%| | 0/10 [00:00<?, ?it/s]1
10%|█ | 1/10 [00:00<00:00, 9.49it/s]2
40%|████ | 4/10 [00:00<00:00, 9.56it/s]3
4
50%|█████ | 5/10 [00:00<00:00, 9.59it/s]5
6
70%|███████ | 7/10 [00:00<00:00, 9.59it/s]7
8
90%|█████████ | 9/10 [00:00<00:00, 9.58it/s]9
100%|██████████| 10/10 [00:01<00:00, 9.59it/s]
等等。。。。
'''

"""

【inspect】
关于python中inspect模块的一些探究

标签: Python

前言

我在学习到实战Day5 - python教程 - 廖雪峰的官方网站时,遇到了inspect模块,之前对这个inspect模块一无所知啊,所以本着打破砂锅问到底的精神,决定对inspect模块做一些探究。

根据度娘搜到的,inspect模块主要提供了四种用处:

(1). 对是否是模块,框架,函数等进行类型检查。

(2). 获取源码

(3). 获取类或函数的参数的信息

(4). 解析堆栈

我在这次课程中,只用到了第三种用处,即获取类或函数的参数的信息,下面我来探究一下。

探究

结合我正在学习的课程,我自己也对inspect做了一些探究。根据在课程中用到的一些函数及方法,我做了一个python脚本。

test

import inspect
def a(a, b=0, *c, d, e=1, **f):
pass
aa = inspect.signature(a)
print("inspect.signature(fn)是:%s" % aa)
print("inspect.signature(fn)的类型:%s" % (type(aa)))
print("\n")

bb = aa.parameters
print("signature.paramerters属性是:%s" % bb)
print("ignature.paramerters属性的类型是%s" % type(bb))
print("\n")

for cc, dd in bb.items():
print("mappingproxy.items()返回的两个值分别是:%s和%s" % (cc, dd))
print("mappingproxy.items()返回的两个值的类型分别是:%s和%s" % (type(cc), type(dd)))
print("\n")
ee = dd.kind
print("Parameter.kind属性是:%s" % ee)
print("Parameter.kind属性的类型是:%s" % type(ee))
print("\n")
gg = dd.default
print("Parameter.default的值是: %s" % gg)
print("Parameter.default的属性是: %s" % type(gg))
print("\n")

ff = inspect.Parameter.KEYWORD_ONLY
print("inspect.Parameter.KEYWORD_ONLY的值是:%s" % ff)
print("inspect.Parameter.KEYWORD_ONLY的类型是:%s" % type(ff))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
执行以上脚本,将得到如下输出:

inspect.signature(fn)是:(a, b=0, *c, d, e=1, **f)
inspect.signature(fn)的类型:<class 'inspect.Signature'>

signature.paramerters属性是:OrderedDict([('a', <Parameter "a">), ('b', <Parameter "b=0">), ('c', <Parameter "*c">), ('d', <Parameter "d">), ('e', <Parameter "e=1">), ('f', <Parameter "**f">)])
ignature.paramerters属性的类型是<class 'mappingproxy'>

mappingproxy.items()返回的两个值分别是:a和a
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>

Parameter.kind属性是:POSITIONAL_OR_KEYWORD
Parameter.kind属性的类型是:<enum '_ParameterKind'>

Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>

mappingproxy.items()返回的两个值分别是:b和b=0
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>

Parameter.kind属性是:POSITIONAL_OR_KEYWORD
Parameter.kind属性的类型是:<enum '_ParameterKind'>

Parameter.default的值是: 0
Parameter.default的属性是: <class 'int'>

mappingproxy.items()返回的两个值分别是:c和*c
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>

Parameter.kind属性是:VAR_POSITIONAL
Parameter.kind属性的类型是:<enum '_ParameterKind'>

Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>

mappingproxy.items()返回的两个值分别是:d和d
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>

Parameter.kind属性是:KEYWORD_ONLY
Parameter.kind属性的类型是:<enum '_ParameterKind'>

Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>

mappingproxy.items()返回的两个值分别是:e和e=1
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>

Parameter.kind属性是:KEYWORD_ONLY
Parameter.kind属性的类型是:<enum '_ParameterKind'>

Parameter.default的值是: 1
Parameter.default的属性是: <class 'int'>

mappingproxy.items()返回的两个值分别是:f和**f
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>

Parameter.kind属性是:VAR_KEYWORD
Parameter.kind属性的类型是:<enum '_ParameterKind'>

Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>

inspect.Parameter.KEYWORD_ONLY的值是:KEYWORD_ONLY
inspect.Parameter.KEYWORD_ONLY的类型是:<enum '_ParameterKind'>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
总结

inspect.signature(fn)将返回一个inspect.Signature类型的对象,值为fn这个函数的所有参数

inspect.Signature对象的paramerters属性是一个mappingproxy(映射)类型的对象,值为一个有序字典(Orderdict)。

这个字典里的key是即为参数名,str类型

这个字典里的value是一个inspect.Parameter类型的对象,根据我的理解,这个对象里包含的一个参数的各种信息

inspect.Parameter对象的kind属性是一个_ParameterKind枚举类型的对象,值为这个参数的类型(可变参数,关键词参数,etc)

inspect.Parameter对象的default属性:如果这个参数有默认值,即返回这个默认值,如果没有,返回一个inspect._empty类。

【from inspect import Signature】【获取参数信息】

"""

练习1

rfind 返回最后次出现的位置,参数一是开始查找位置,参数二是结束查找位置

str1 = 'admin minad entend'
print(str1.rfind(' ',0,6)) #5
print(str1.rfind(' ',0,2)) #-1
print(str1.rfind(' ',2)) #11
print(str1.find(' ',2)) #5

print(str1[:5].rstrip()) #admin
"""

练习2

def clip(text,max_len=80):
'''在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.find(' ',max_len)
if space_after > 0:
end = space_after
if end is None:
end = len(text)
return text[:end].rstrip()

提取关于函数参数的信息

print(clip.defaults) #(80,)
print(clip.code) #<code object clip at 0x0000000001DA5930, file "C:/Users/wangxue1/PycharmProjects/python2/methodIsObj/init.py", line 13>
print(clip.code.co_varnames) #('text', 'max_len', 'end', 'space_before', 'space_after')
print(clip.code.co_argcount) #2

提取函数的签名

from inspect import signature
sig = signature(clip)
print(sig) #(text, max_len=80)
print(str(sig)) #(text, max_len=80)
for name,param in sig.parameters.items():
print(param.kind,':',name,'=',param.default)
'''
POSITIONAL_OR_KEYWORD : text = <class 'inspect._empty'>
POSITIONAL_OR_KEYWORD : max_len = 80
'''

【备注】

'''
kind 属性的值是 _ParameterKind 类中的 5 个值之一,列举如下。
POSITIONAL_OR_KEYWORD
  可以通过定位参数和关键字参数传入的形参(多数 Python 函数的参数属于此类)。
VAR_POSITIONAL
  定位参数元组。
VAR_KEYWORD
  关键字参数字典。
KEYWORD_ONLY
  仅限关键字参数(Python 3 新增)。
POSITIONAL_ONLY
  仅限定位参数;目前, Python 声明函数的句法不支持,但是有些使用 C 语言实现且
不接受关键字参数的函数(如 divmod)支持
'''

吧tag函数的签名绑定到一个参数字典上

...准备工作

def tag(name,*content,cls=None,**attrs):
if cls is not None:
attrs['class'] = cls
if attrs:
attr_str = ''.join()
attrs = {'class':'sidebar'}
print('%s="%s' % (attr,value) for attr,value in sorted(attrs.items())) #<generator object at 0x000000000220A830>
print(''.join('%s="%s' % (attr,value) for attr,value in sorted(attrs.items()))) #class="sidebar
print(''.join('%s="%s' % (attr,value) for attr,value in (attrs.items()))) #class="sidebar
print(attrs.items()) #dict_items([('class', 'sidebar')])
print(sorted(attrs.items())) #[('class', 'sidebar')]

...tag函数

def tag(name,*content,cls=None,**attrs):
'''生成一个或多个HTML标签'''
if cls is not None:
attrs['class'] = cls
if attrs:
attr_str = ''.join(' %s="%s' % (attr,value) for attr,value in sorted(attrs.items()))
else:
attr_str = ''
if content:
return '\n'.join('<%s%s>%s</%s>' % (name,attr_str,c,name) for c in content)
else:
return '<%s%s />' % (name,attr_str)

sig = signature(tag)
my_tag = {'name':'img','title':'Sunset Boulevard','src':'sunset.jpg','cls':'framed'}
bound_args = sig.bind(**my_tag)
print(bound_args) #<BoundArguments (name='img', cls='framed', attrs={'title': 'Sunset Boulevard', 'src': 'sunset.jpg'})>
for name,value in bound_args.arguments.items():
print(name,'=',value)
'''
name = img
cls = framed
attrs = {'title': 'Sunset Boulevard', 'src': 'sunset.jpg'}
'''

del my_tag['name']

bound_args = sig.bind(**my_tag) #TypeError: missing a required argument: 'name'

【inspect】
名称 含义
POSITIONAL_ONLY 必须为位置参数,python没有明确定义位置参数的语法
POSITIONAL_OR_KEYWORD 可以为位置参数或者关键字参数
VAR_POSITIONAL 位置参数的元素没有绑定到任何其他参数,对应python函数定义中的args(可变参数)
KEYWORD_ONLY 值必须作为关键字参数提供,只有关键字参数是指出现在或者*args之后的参数(命名关键字参数)
VAR_KEYWORD 没有绑定到任何其他参数的关键字参数的字典,对应参数定义的**kwargs(关键字参数)
上面就是各参数类型的含义,下面来个例子:

import inspect

def foo(a, b, *args,c, **kwargs):
pass

sig = inspect.signature(foo)
for name, param in sig.parameters.items():
print('参数:%s的类型为:%s' % (name, param.kind))

输出结果如下:

参数:a的类型为:POSITIONAL_OR_KEYWORD
参数:b的类型为:POSITIONAL_OR_KEYWORD
参数:args的类型为:VAR_POSITIONAL
参数:c的类型为:KEYWORD_ONLY
参数:kwargs的类型为:VAR_KEYWORD

前言

我在学习到实战Day5 - python教程 - 廖雪峰的官方网站时,遇到了inspect模块,之前对这个inspect模块一无所知啊,所以本着打破砂锅问到底的精神,决定对inspect模块做一些探究。

根据度娘搜到的,inspect模块主要提供了四种用处:

(1). 对是否是模块,框架,函数等进行类型检查。

(2). 获取源码

(3). 获取类或函数的参数的信息

(4). 解析堆栈

我在这次课程中,只用到了第三种用处,即获取类或函数的参数的信息,下面我来探究一下。

探究

结合我正在学习的课程,我自己也对inspect做了一些探究。根据在课程中用到的一些函数及方法,我做了一个python脚本。
test

import inspect
def a(a, b=0, *c, d, e=1, **f):
pass
aa = inspect.signature(a)
print("inspect.signature(fn)是:%s" % aa)
print("inspect.signature(fn)的类型:%s" % (type(aa)))
print("\n")

bb = aa.parameters
print("signature.paramerters属性是:%s" % bb)
print("ignature.paramerters属性的类型是%s" % type(bb))
print("\n")

for cc, dd in bb.items():
print("mappingproxy.items()返回的两个值分别是:%s和%s" % (cc, dd))
print("mappingproxy.items()返回的两个值的类型分别是:%s和%s" % (type(cc), type(dd)))
print("\n")
ee = dd.kind
print("Parameter.kind属性是:%s" % ee)
print("Parameter.kind属性的类型是:%s" % type(ee))
print("\n")
gg = dd.default
print("Parameter.default的值是: %s" % gg)
print("Parameter.default的属性是: %s" % type(gg))
print("\n")

ff = inspect.Parameter.KEYWORD_ONLY
print("inspect.Parameter.KEYWORD_ONLY的值是:%s" % ff)
print("inspect.Parameter.KEYWORD_ONLY的类型是:%s" % type(ff))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
执行以上脚本,将得到如下输出:

inspect.signature(fn)是:(a, b=0, *c, d, e=1, **f)
inspect.signature(fn)的类型:<class 'inspect.Signature'>

signature.paramerters属性是:OrderedDict([('a', <Parameter "a">), ('b', <Parameter "b=0">), ('c', <Parameter "*c">), ('d', <Parameter "d">), ('e', <Parameter "e=1">), ('f', <Parameter "**f">)])
ignature.paramerters属性的类型是<class 'mappingproxy'>

mappingproxy.items()返回的两个值分别是:a和a
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>

Parameter.kind属性是:POSITIONAL_OR_KEYWORD
Parameter.kind属性的类型是:<enum '_ParameterKind'>

Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>

mappingproxy.items()返回的两个值分别是:b和b=0
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>

Parameter.kind属性是:POSITIONAL_OR_KEYWORD
Parameter.kind属性的类型是:<enum '_ParameterKind'>

Parameter.default的值是: 0
Parameter.default的属性是: <class 'int'>

mappingproxy.items()返回的两个值分别是:c和*c
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>

Parameter.kind属性是:VAR_POSITIONAL
Parameter.kind属性的类型是:<enum '_ParameterKind'>

Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>

mappingproxy.items()返回的两个值分别是:d和d
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>

Parameter.kind属性是:KEYWORD_ONLY
Parameter.kind属性的类型是:<enum '_ParameterKind'>

Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>

mappingproxy.items()返回的两个值分别是:e和e=1
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>

Parameter.kind属性是:KEYWORD_ONLY
Parameter.kind属性的类型是:<enum '_ParameterKind'>

Parameter.default的值是: 1
Parameter.default的属性是: <class 'int'>

mappingproxy.items()返回的两个值分别是:f和**f
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>

Parameter.kind属性是:VAR_KEYWORD
Parameter.kind属性的类型是:<enum '_ParameterKind'>

Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>

inspect.Parameter.KEYWORD_ONLY的值是:KEYWORD_ONLY
inspect.Parameter.KEYWORD_ONLY的类型是:<enum '_ParameterKind'>

总结

inspect.signature(fn)将返回一个inspect.Signature类型的对象,值为fn这个函数的所有参数

inspect.Signature对象的paramerters属性是一个mappingproxy(映射)类型的对象,值为一个有序字典(Orderdict)。

这个字典里的key是即为参数名,str类型

这个字典里的value是一个inspect.Parameter类型的对象,根据我的理解,这个对象里包含的一个参数的各种信息

inspect.Parameter对象的kind属性是一个_ParameterKind枚举类型的对象,值为这个参数的类型(可变参数,关键词参数,etc)

inspect.Parameter对象的default属性:如果这个参数有默认值,即返回这个默认值,如果没有,返回一个inspect._empty类。

posted @ 2018-08-07 09:05  素人渔芙2017  阅读(928)  评论(0编辑  收藏  举报