8.1 定义函数
def greet_user(): #无参函数
def greet_user(name): #有参函数
8.2 传递实参
8.2.1 位置实参
实参的顺序与形参的顺序相同。根据位置来传递参数。<br />![image.png](https://cdn.nlark.com/yuque/0/2019/png/267778/1553744157731-0f4099eb-6b14-4e8c-8ae9-d6cfc7199baa.png#crop=0&crop=0&crop=1&crop=1&height=148&id=Yqcip&name=image.png&originHeight=267&originWidth=2039&originalType=binary&ratio=1&rotation=0&showTitle=false&size=33471&status=done&style=none&title=&width=1133)<br />
8.2.2 关键字实参
调用函数时,在实参中明确指出形参的变量名并赋值,以此来传递参数,不用在意实参的位置顺序。<br />![image.png](https://cdn.nlark.com/yuque/0/2019/png/267778/1553744196668-62f8949a-e5e3-4dc9-97bf-56eea8b59139.png#crop=0&crop=0&crop=1&crop=1&height=182&id=bikp0&name=image.png&originHeight=328&originWidth=2034&originalType=binary&ratio=1&rotation=0&showTitle=false&size=31906&status=done&style=none&title=&width=1130)
8.2.3 形参默认值
定义函数时,可以给形参指定默认值,但带默认值的形参必须放在最后。<br /> 调用函数时,如果不对带默认值的参数提供实参,则使用默认值。否则使用指定的新值。<br /> 调用函数时同时得注意,是采用哪种方式传递实参。<br />![image.png](https://cdn.nlark.com/yuque/0/2019/png/267778/1553744257425-f2159162-66b6-4b98-a98b-437481cb500f.png#crop=0&crop=0&crop=1&crop=1&height=257&id=DYPwm&name=image.png&originHeight=463&originWidth=2044&originalType=binary&ratio=1&rotation=0&showTitle=false&size=61330&status=done&style=none&title=&width=1136)<br />注意:默认值必须是“**不可变对象**”immutable type,否则可能会出现问题(具体看情况):因为如果默认值是可变对象,函数传参采用的是引用,于是你每调用一次,这个可变对象都有可能发生改变。例如下面的情况
def add_end(L=[]):
L.append('END')
return L
8.3 返回值
8.3.1 返回简单值
定义函数时,里面的return语句回返回指定的值
def get_formatted_name(f_name, l_name):
full_name = f_name + ' ' + l_name
return full_name #在return语句后面指出需要返回的值
temp = get_formatted_name("Mesut", "Ozil") #使用函数的返回值,需要将它存入一个中间变量。
print(temp)
8.3.2 实参可选的操作
在定义函数时,对形参设置“空的”默认值,且放在形参最后。<br /> 再通过if-else语句对什么情况下使用那些参数,采用什么操作,来进行选择,达到实参可选的目的。(即在每次调用时,实参的个数可以不一样)<br /> (例子见书P122, pdf72)
注意:函数能返回任何类型的值,包括列表和字典。
- 分析:其实所谓的“可选”,就是设置了带“默认值”的形参而已,跟函数里用不用if无关
8.4 传递列表
即实参是一个列表。例子见书P127,pdf74
由于定义形参时,是不需要指定参数类型的,理论上你可以传递任意类型的实参。但是往往在定义函数时,其中的操作就已经决定了这个函数在调用时的实参,应该是一个什么类型的数据。
注:当使用函数对列表进行操作时,若不希望函数修改原有列表,可以在调用函数时,将实参指定为列表的副本,即利用“切片”复制列表。
print_models(unprinted_designs[:], completed_models)
8.5 传递任意数量的实参
不要管以下这几个参数的名字,估计是翻译有问题,了解功能就好。
(一共三种:1. 一星的:元组;2. 两星的:字典;3. 限制字典key的名字的)
定义函数时,在形参变量前加星号(*variable)。这样,无论调用函数时的实参有多少,函数都是一个一个处理的。
8.5.1 结合使用位置实参和任意数量实参
- 形参toppings前的星号()让python创建了一个名为toppings的空元组,并将接收到的所有值都封装到这个元组中。 (又叫“可变参数”) ```python def make_pizza(toppings): print(*toppings) print(toppings[1])
make_pizza(‘cocount’, ‘boba’)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/267778/1656219387428-2ba17495-062d-418f-92c3-1eca6bb20ce2.png#clientId=u6e113030-054d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=146&id=ufd3f2a0d&name=image.png&originHeight=292&originWidth=2018&originalType=binary&ratio=1&rotation=0&showTitle=false&size=122626&status=done&style=none&taskId=u2642ed9d-25fb-4bdb-ae1f-5670723b905&title=&width=1009)<br />
<a name="983852d7"></a>
### 8.5.2 使用任意数量的关键字实参
2. **让python创建了一个名为user_info的**空字典**,并将收到的所有键值对都封装到这个字典中。在这个函数中,可以像访问其他字典那样访问 user_info 中的名称 — 值对。(又叫:“关键字参数”)
```python
def build_profile(first, last, **user_info):
(例子见书P131,pdf77)
(其实只是看着像关键字,实际上存进去的是键值对(字典嘛))
- 限制关键字实参名字的方法(但其实这个时候也就不可变了) (又叫:“命名关键字参数”)
和关键字参数**kw
不同,命名关键字参数需要一个特殊分隔符*
,*
后面的参数被视为命名关键字参数。
但是如果之前有了一个“一星的”(传入元组),后面跟着的命名关键字参数就不再需要一个特殊分隔符*
了
def person(name, age, *args, city, job):
print(name, age, args, city, job)
同时,这种限制关键字参数,本身也能先指定默认值。这样即使你不传入city,也没有关系
def person(name, age, *, city='Beijing', job):
print(name, age, city, job)
重点:在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
8.6 将函数存储在模块中
8.6.1 导入整个模块
使用import语句导入整个模块,再调用模块中的函数。(调用时要指定被调用的函数名及它的模块,用.分隔)
import pizza
pizza.make_pizza(16, 'pepperoni')
8.6.2 导入模块中的特定函数
语法: from module_name import function_name #function_name可以有多个,用逗号分隔就行
from pizza import make_pizza
make_pizza(16, 'pepperoni') #此时的调用不需要指出函数出自于哪个模块,直接调用函数名即可。
8.6.3 使用as给函数指定别名
语法: from module_name import function_name as new_function_name
from pizza import make_pizza as mp
mp(16, 'pepperoni')
8.6.4 使用as给模块指定别名
语法: import module_name as new_module_name
import pizza as p
p.make_pizza(16, 'pepperoni')
8.6.5 导入模块中的所有函数
语法: from module_name import *
from pizza import *
make_pizza(16, 'pepperoni')
注意:最好少采用这种方法,如果一旦模块中有函数的名称与已有函数名称重合,可能会出现意想不到的错误。<br />
第八章小结
1.编写函数时,每个函数都只应该负责一项具体的工作,这样有利于程序的扩展和维护。
2.函数的名称中只使用小写字母加下划线。
3.给形参指定默认值时,等号两边不要留空格;实参如果有采用关键字实参,等号两边也不要留空格。