python函数参数学习笔记
1、参数的传递是通过自动将对象赋值给本地变量名来实现的。函数参数(调用者发送的(可能的)共享对象的引用值),所有的参数实际上都是通过指针进行传递的。作为参数被传递的对象从里不自动拷贝。 2、在函数内部的参数名的赋值不会影响调用者。在函数运行时,在函数头部的参数名是一个新的、本地变了,这个变量名时再函数的本地作用域内的。函数参数名和调用者作用域的变量名是没有别名的。 3、改变函数的可变对象的参数也许会对调用者有影响。换句话说,因为参数是简单的赋值给传入对象。函数能够就地的改变传入的可变对象,因此其结果影响调用者。可变参数对于函数来说是可以做输入和输出的。 4、不可变参数“通过值”进行拷贝的。像整数和字符串这样的对象通过对象引用而不是拷贝进行传递的,但是因为你无聊怎样都不可能在原处改变不可变对象,实际效果就很像创建一份拷贝。 5、可变对象是通过“指针”进行传递的。例如,列表和字典这样的对象也就是通过对象引用进行传递的,这点与C语言使用的指针传递数组很相似:可变对象那个在函数内部进行原处的改变,这一点和C数组很像。 例如: def f(a,b): a = 100 b[0]='spam' x = 1 y = [1,2] f(x,y) print(x,y) #输出:100,['spam',2] 因为给a传递的是数字,数字不可变,但是b可以改变 6、参数传递的几种方式 位置:从左到右进行匹配。 关键字参数:通过参数名进行匹配 默认参数:为没有传入值的参数定义参数值 可变参数:手机任意多基于位置或者关键字的参数:(调用者能够再使用*语法去将参数集合打散,分成参数,这个*与在函数头部的*恰恰相反,在函数头部的它意味着收集任意多的参数,而在调用中意味着传递任意多的参数。) Keywod-only参数:参数必须按照名称传递:(在python3.0中(不包括python2.6))函数也可以指定参数,参数必须用带有关键字参数的名字来传递。这样的参数通常用来地宫一实际参数以外配置选项。 7、例子: func(value) 常规参数传递,通过位置进行匹配 func(name=value) 关键字参数,通过变量名匹配 func(*sequence) 以name传递所有对象,并作为独立的基于位置的参数 func(**dict) 以name成对的传递所有的关键字/值,并作为独立的关键字参数 def func(name) 常规参数:通过位置或变量名进行匹配 def func(name=value) 默认值参数,如果没有在调用者中传递的话 def func(*name) 匹配并收集在元祖中所包含位置参数 def func(**name) 匹配并收集在字典中的所有包含位置的参数 def func(*args,name) 参数必须在调用中按照关键字传递 def func(*,name=value) python3.0中有的 8、如果决定使用并混合特定的参数匹配模型,Python将会遵循下面有关 顺序法则。 (在函数调用中,参数必须以此属性出现:任何位置参数(value),后面跟着任何关键字参数(name=value)和*sequence像是的组合,后面跟着**dict形式) (在函数头部,参数必须以此书序出现;任何一般参数(name),紧跟着任何默认参数(name=value),如果有的话,后面是*name(或者在python3.0中是*)形式,后面跟着任何name或者name=value kyeword-only(在python3.0中)后面跟着**name形式) 9、任意参数的实例 例如: * def f(*arg):print(arg) f() #输出:() f(1)#输出:(1,) f(1,2,3,4,5)#输出:(1,2,3,4,5) **能够对多余的关键字参数有效,将多余的关键字参数转化为字典。 def (**arg):print(arg) f() #输出:{} f(a=1,b=2) #输出:{’a':1,'b':2} 混合用法: def f(a,*arg,**kargs):print(a,arg,kargs) f(1,2,3,x=1,y=x) #输出:1,(2,3){'x':1,'y':2} 10、解包参数 *解包元祖,列表,集合,字符串 def func(a,b,c,d):print(a,b,c,d) arg = (1,2) arg += (3,4) func(*args) #输出:1,2,3,4 **解包字典,使其成为独立的关键字参数(就是说键必须跟函数定义时的参数同名) d = {'a':1,'b':2,'c':3,'d':4} f(**d)#输出:1,2,3,4 #错误的:d = {'x':1,'y':2,'z':3,'t':4} f(**t) 会报错 11、python3.0 Keysword-Only关键字参数 语法: keyword-onl参数编码为命名的参数,出现在参数列表*args之后,所有的这些参数必须在调用中使用关键字语法来传递。例如下面的代码:a可能按照名称或者位置传递,b可以收集任意额外的位置参数,并且C必须只按照关键字攒地 def f(a,*b,c): print(a,b,c) f(1,2,c=3) #输出;1 (2,) 3 f(a=1,c=3) #输出:1 () 3 #f(1,2,3) 报错 我们可以在参数列表中使用一个*字符,来表示一个函数不会接受一个变量长度参数列表,而仍然期待跟在*后面的所有字符都作为关键字传递。在下一个函数中,a可能再次按照位置或者名称传递,但是b和c必须按照关键字传递,不允许其他额外的位置传递 def f(a,*,b,c): print(a,b,c) f(1,c=3,b=2) #输出:1,2,3 f(c=3,b=2,a=1) #输出:1,2,3 #f(1,2,3) 和f(1)都会报错。 仍然可以对keyword——only参数使用默认值,即便他们出现在函数的头部中*后面,在下面的代码中,a可能按照名次或者位置传递,而b和c是可选的,但是如果使用的话必须按照关键字传递: def f(a,*,b='spam',c='ham'): print(a,b,c) f(1) #输出:1,spam,ham f(1,c=3) #输出:1,spam,3 f(a=1) #输出:1,spam,ham f(c=3,a=1,b=2) #输出:1,2,3 12、keyword-only定义时排序规则 keyword-only参数必须在一个单个星号后面指定,而不是两个星号前。这意味着,在一个函数头部,keyword-only参数必须编写在**args关键字参数之前,且在*arg任意位置形式之后。当二者都有的时候,无论何时,一个参数名称出现在*args之前,它可能是默认位置参数,而不是keyword_only参数。 #错误的def f(a,*b,**d,c=6):print(a,b,c,d) #正确的 def f(a,*b,c=6,**d):print(a,b,c,d) f(1,2,3,x=4,y=5) #输出:1 (2,3) 6 {'x':4,'y':5} f(1,2,3,x=4,y=5,c=7) #输出:1 (2,3) 7 {'x':4,'y':5} f(1,2,3,c=7,x=4,y=5) #输出:1 (2,3) 7 {'x':4,'y':5} 但是最后一个不是keyword-only参数了 def f(a,c=6,*b,**d):print(a,b,c,d) f(1,2,3,x=4) #输出:1 (3,) 2{'x':4} 13、keyword-only调用时排序规则 在函数调用中,当传递keyword-only参数的时候,他们必须出现在**args形式之前。keyword-only参数可以出现在*arg之前或者之后,也有可能包含在**arg中 def f(a,*b,c=6,**d) 14、模拟python3.0中的print函数 def print30(*args,**kargs): sep = kargs.get('seq',' ') end = kargs.get('end','\n') file = kargs.get('file',sys.stdout) output = '' first = true for arg in args: output += ('' if first else sep))+str(arg) first = false file.write(output+end)