关于位置参数(必选参数)、默认参数、可变参数、关键字参数这些定义:
参数定义顺序:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
可参考: Python的位置参数、默认参数、关键字参数、可变参数
位置参数:power(x, n)中的x和n就是位置参数,位置参数必须传入,并且会按照位置依次赋值。
power(x, n=2),其中n=2表示一个默认参数。定义默认参数要牢记一点:默认参数必须指向不变对象!可设置为None
默认参数可以简化函数的调用,设置默认参数时,有几点要注意:
一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
二是如何设置默认参数,当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
可变参数
命名关键字参数
关键字参数
组合:
def f1(a, b, c=0, *args, **kw): # 位置参数a、b;默认参数c;可变参数args;关键字参数kw
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
def f2(a, b, c=0, *, d, **kw): # 位置参数a、b;默认参数c;命名关键字参数d;关键字参数kw
print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
'''example'''
f1(1, 2)
# a = 1 b = 2 c = 0 args = () kw = {}
f1(1, 2, c=3)
# a = 1 b = 2 c = 3 args = () kw = {}
f1(1, 2, 3, 'a', 'b')
# a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
f1(1, 2, 3, 'a', 'b', x=99)
# a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
f2(1, 2, d=99, ext=None)
# a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}
args = (1, 2, 3, 4)
kw = {'d': 99, 'x': '#'}
f1(*args, **kw)
# a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'}
args = (1, 2, 3)
kw = {'d': 88, 'x': '#'}
f2(*args, **kw)
# a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}
# 所以,对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的。
关于函数调用参数的传递方式是值传递还是引用传递:
可变类型有list,dict,set ,不可变类型有string,number,tuple.
当进行修改操作时,可变类型传递的是内存中的地址,也就是说,直接修改内存中的值,并没有开辟新的内存。
不可变类型被改变时,并没有改变原内存地址中的值,而是开辟一块新的内存,将原地址中的值复制过去,对这块新开辟的内存中的值进行操作。
不可变参数(字符串,元组,int)用值传递:像整数和字符串这样的不可变对象,是通过拷贝进行传递的,因为你无论如何都不可能在原处改变不可变对象。
可变参数(列表,字典,集合)是引用传递:比如像列表,字典这样的对象是通过引用传递、和C语言里面的用指针传递数组很相似,可变对象能在函数内部改变。
Python中一切皆对象,函数名是函数在内存中的空间,也是一个对象