前言
继续本周的学习,
一、函数
函数定义时可能包含多个形参,因此函数调用中也可能包含多个实参,向函数传递实参的方式很多:可以使用位置实参,也可使用关键字实参。
1.位置实参
基于实参的顺序,将其关联到形参。
def describe_pet(animal_type,pet_name):
print("I have a {animal_type}.".format(animal_type = animal_type))
print("My {animal_type} name is {pet_name}".format(animal_type = animal_type,pet_name = pet_name))
describe_pet('harry','hamster')
这个例子中,第一个实参'harry'
传递给了animal_type
形参。
2.关键字实参
describe_pet(animal_type = 'harry',pet_name = 'hamster')
明确的指明了将实参传给哪个形参。与顺序无关。
3.默认值
可以在定义函数时,给形参赋予默认值,在调用时,如果没有给该形参赋值,则为默认值。在定义时,必须将带有默认值的形参写在不带有默认值的形参之后,这是为了依然能够正确解读位置实参。
4.让实参变成可选的
有时候函数中的某个形参,我们可能需要它,也可能不需要它,在调用时,为了保证函数都能正常运行,将这个形参默认值设为‘ ’
,放到最后,这样调用的时候,如果没有这个实参,其默认值为空,如果有这个实参,指定其值。
5.向函数传递列表
如果我们向函数传递一个列表,在函数中对列表进行修改,会对实参的列表也一并修改(理解为,传递的是列表的地址)
例如
a = [1,2,3,4]
def list_a(a):
a.pop()
list_a(a)
a
[1, 2, 3]
可以看到在函数中对列表a删除了最后一个元素,调用完函数之后,在函数之外,列表a确实发生了变化。
如果我们想要只是在函数内部,列表发生变化,而实际的列表a不发生变化,应该如何操作呢?
可以传入列表a的副本。如下所示
a = [1,2,3,4]
list_a(a[:])
a
[1, 2, 3, 4]
6.传递任意数量的实参
如果不知道函数需要接受多少个参数,在函数定义时,可以只定义一个形参。
例如
def deng(*x):
print(x)
deng(1)
(1,)
deng(1,2,3,4)
(1, 2, 3, 4)
可以看到,在形参前加一个*
号,这个形参可以接受任意数量实参,将所有实参转化为一个元组。
注意,如果还有其他位置实参或是关键字实参,我们需要将*args
放在其他形参之后。
7.传递任意数量的关键字实参
如果我们要接受任意数量的实参,但是不知道传递给函数的是什么样的信息。可以将函数编写成能够接受任意数量的键值对。
示例如下:
def build_profile(first_name,last_name,**user_name):
user_name['first_name'] = first_name
user_name['last_name'] = last_name
return user_name
user_profile = build_profile('deng','chao',location = 'princeton',field = 'physics')
print(user_profile)
{
'location': 'princeton', 'field': 'physics', 'first_name': 'deng', 'last_name': 'chao'}
在定义函数时,我在形参user_name前加了加了两个**
,这个的作用就是,将后续的参数都以键值对的形式存储到字典user_name中,并且在函数内部,也可以访问这个字典user_name。