1. 不同类型的参数简述#这里先说明python函数调用得语法为:复制代码 代码如下:func(positional_args, keyword_args, *tuple_grp_nonkw_args, **dict_grp_kw_args) #为了方便说明,之后用以下函数进行举例 def test(a,b,c,d,e): print a,b,c,d,e举个例子来说明这4种调用方式得区别:复制代码 代码如下:##positional_args方式>>> test(1,2,3,4,5)1 2 3 4 5#这种调用方式的函数处理等价于a,b,c,d,e = 1,2,3,4,5print a,b,c,d,e##keyword_args方式>>> test(a=1,b=3,c=4,d=2,e=1)1 3 4 2 1#这种处理方式得函数处理等价于a=1b=3c=4d=2e=1print a,b,c,d,e##*tuple_grp_nonkw_args方式>>> x = 1,2,3,4,5>>> test(*x)1 2 3 4 5#这种方式函数处理等价于复制代码 代码如下:a,b,c,d,e = xprint a,b,c,d,e#特别说明:x也可以为dict类型,x为dick类型时将键传递给函数>>> y{'a': 1, 'c': 6, 'b': 2, 'e': 1, 'd': 1}>>> test(*y)a c b e d##**dict_grp_kw_args方式>>> y{'a': 1, 'c': 6, 'b': 2, 'e': 1, 'd': 1}>>> test(**y)1 2 6 1 1#这种函数处理方式等价于a = y['a']b = y['b']... #c,d,e不再赘述print a,b,c,d,e2. 不同类型参数混用需要注意的一些细节 接下来说明不同参数类型混用的情况,要理解不同参数混用得语法需要理解以下几方面内容. 首先要明白,函数调用使用参数类型必须严格按照顺序,不能随意调换顺序,否则会报错. 如 (a=1,2,3,4,5)会引发错误,; (*x,2,3)也会被当成非法. 其次,函数对不同方式处理的顺序也是按照上述的类型顺序.因为#keyword_args方式和**dict_grp_kw_args方式对参数一一指定,所以无所谓顺序.所以只需要考虑顺序赋值(positional_args)和列表赋值(*tuple_grp_nonkw_args)的顺序.因此,可以简单理解为只有#positional_args方式,#*tuple_grp_nonkw_args方式有逻辑先后顺序的. 最后,参数是不允许多次赋值的. 举个例子说明,顺序赋值(positional_args)和列表赋值(*tuple_grp_nonkw_args)的逻辑先后关系:复制代码 代码如下:#只有在顺序赋值,列表赋值在结果上存在罗辑先后关系#正确的例子1>>> x = {3,4,5}>>> test(1,2,*x)1 2 3 4 5#正确的例子2>>> test(1,e=2,*x)1 3 4 5 2#错误的例子>>> test(1,b=2,*x)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: test() got multiple values for keyword argument 'b'#正确的例子1,处理等价于a,b = 1,2 #顺序参数c,d,e = x #列表参数print a,b,c,d,e#正确的例子2,处理等价于a = 1 #顺序参数e = 2 #关键字参数b,c,d = x #列表参数#错误的例子,处理等价于a = 1 #顺序参数b = 2 #关键字参数b,c,d = x #列表参数#这里由于b多次赋值导致异常,可见只有顺序参数和列表参数存在罗辑先后关系函数声明区别 理解了函数调用中不同类型参数得区别之后,再来理解函数声明中不同参数得区别就简单很多了.1. 函数声明中的参数类型说明 函数声明只有3种类型, arg, *arg , **arg 他们得作用和函数调用刚好相反. 调用时*tuple_grp_nonkw_args将列表转换为顺序参数,而声明中的*arg的作用是将顺序赋值(positional_args)转换为列表. 调用时**dict_grp_kw_args将字典转换为关键字参数,而声明中**arg则反过来将关键字参数(keyword_args)转换为字典.特别提醒:*arg 和 **arg可以为空值.以下举例说明上述规则:复制代码 代码如下:#arg, *arg和**arg作用举例def test2(a,*b,**c): print a,b,c##*arg 和 **arg可以不传递参数>>> test2(1)1 () {}#arg必须传递参数>>> test2()Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: test2() takes at least 1 argument (0 given)##*arg将顺positional_args转换为列表>>> test2(1,2,[1,2],{'a':1,'b':2})1 (2, [1, 2], {'a': 1, 'b': 2}) {}#该处理等价于a = 1 #arg参数处理b = 2,[1,2],{'a':1,'b':2} #*arg参数处理c = dict() #**arg参数处理print a,b,c##**arg将keyword_args转换为字典>>> test2(1,2,3,d={1:2,3:4}, c=12, b=1)1 (2, 3) {'c': 12, 'b': 1, 'd': {1: 2, 3: 4}}#该处理等价于a = 1 #arg参数处理b= 2,3 #*arg参数处理#**arg参数处理c = dict()c['d'] = {1:2, 3:4}c['c'] = 12c['b'] = 1print a,b,c2. 处理顺序问题 函数总是先处理arg类型参数,再处理*arg和**arg类型的参数. 因为*arg和**arg针对的调用参数类型不同,所以不需要考虑他们得顺序.复制代码 代码如下:def test2(a,*b,**c): print a,b,c>>> test2(1, b=[1,2,3], c={1:2, 3:4},a=1)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: test2() got multiple values for keyword argument 'a'#这里会报错得原因是,总是先处理arg类型得参数#该函数调用等价于#处理arg类型参数:a = 1a = 1 #多次赋值,导致异常#处理其他类型参数...print a,b,c>>> def foo(x,y):... def bar():... print x,y... return bar... #查看func_closure的引用信息>>> a = [1,2]>>> b = foo(a,0)>>> b.func_closure[0].cell_contents[1, 2]>>> b.func_closure[1].cell_contents0>>> b()[1, 2] 0#可变对象仍然能被修改>>> a.append(3)>>> b.func_closure[0].cell_contents[1, 2, 3]>>> b()[1, 2, 3] 0
isinstance(object, class)函数,检查某个对象是不是某个类里的例如:>>>isinstance(1,int)True但是这个能不用就不用,毕竟你只要某个对象有某个方法就好,这样破坏的对象“多态”的特征。
可以是列表。实际上,"参数可以是什么类型"取决于函数体中定义的操作。只要该类型支持这个过程就可以。比如def dummy(a): return a*2可以接受整数或列表作为参数,因为列表也可以实现乘法。想要每个元素乘2的话,a = [i * 2 for i in a]