💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] ***** # 8.1 定义函数 ``` #定义函数 def greet_user(username): """Display a simple greeting.""" print("Hello, " + username.title() + "!") #函数调用 给函数传递参数 greet_user('jesse') ``` #8.1.2 实参和形参 在函数greet_user()的定义中,变量username是一个形参 —— 函数完成其工作所需的一项信息。在代码greet_user('jesse')中,值'jesse'是一个实参。 # 8.2 传递实参 ## 8.2.1 位置实参 将函数调用中的每个实参都关联到函数定义中的一个形参。 为此,最简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参 ``` def describe_pet(animal_type, pet_name): """显示宠物的信息""" print("\nI have a " + animal_type + ".") print("My " + animal_type + "'s name is " + pet_name.title() + ".") describe_pet('hamster', 'harry') ``` 2. 位置实参的顺序很重要 ``` #这样子编程动物类型是harry, 宠物名字是松鼠,和目标不一致错误 describe_pet('harry', 'hamster') ``` ## 8.2.2 关键字实参 关键字实参是传递给函数的名称—值对。你直接在实参中将名称和值关联起来了,因此向函数传递实参时不会混淆(不会得到名为Hamster的harry这样的结果)。关键字实参让你无需考虑函数调用中的实参顺序,还清楚地指出了函数调用中各个值的用途。 ``` def describe_pet(animal_type, pet_name): """显示宠物的信息""" print("\nI have a " + animal_type + ".") print("My " + animal_type + "'s name is " + pet_name.title() + ".") describe_pet(animal_type='hamster', pet_name='harry') ``` ## 8.2.3 默认值 编写函数时,可给每个形参指定默认值。在调用函数中给默认的形参提供了实参时,使用指定的实参值;否则,将使用形参的默认值。给形参指定默认值后,可在函数调用中省略相应的实参。 ``` def describe_pet(pet_name, animal_type='dog'): """显示宠物的信息""" print("\nI have a " + animal_type + ".") print("My " + animal_type + "'s name is " + pet_name.title() + ".") describe_pet(pet_name='willie') ``` 形参是默认值,传参数时实参和形参绑定依然会按照位置绑定 ** 注意** 使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的形参。 ## 8.2.4 等效的函数调用 对于以下函数定义 ``` def describe_pet(pet_name, animal_type='dog'): ``` 有几种等效的函数调用 ``` # 一条名为Willie的小狗 describe_pet('willie') describe_pet(pet_name='willie') # 一只名为Harry的仓鼠 describe_pet ('harry', 'hamster') describe_pet (pet_name='harry', animal_type='hamster') describe_pet(animal_type='hamster', pet_name='harry') ``` ## 8.2.5 避免实参错误 ![](https://img.kancloud.cn/ad/a4/ada4e00828beaceadc36f8269d858d02_414x210.png) # 8.3 返回值 ## 8.3.1 返回简单值 ``` def get_formatted_name(first_name, last_name): """返回整洁的姓名""" full_name = first_name + ' ' + last_name return full_name.title() musician = get_formatted_name('jimi', 'hendrix') print(musician) ``` ## 8.3.2 让实参变成可选的 给函数的形参指定默认值为空。不用该参数时不传值。使用参数时,给实参赋值覆盖原来的默认值 ``` def get_formatted_name(first_name, last_name, middle_name=''): musician = get_formatted_name('john', 'hooker', 'lee') ``` ## 8.3.3 返回字典 ``` def build_person(first_name, last_name, age=''): """Return a dictionary of information about a person.""" person = {'first': first_name, 'last': last_name} return person ``` # 8.4 传递列表 ``` def greet_users(names): """Print a simple greeting to each user in the list.""" for name in names: msg = "Hello, " + name.title() + "!" print(msg) usernames = ['hannah', 'ty', 'margot'] greet_users(usernames) ``` ## 8.4.1 在函数中修改列表 将列表传递给函数后,函数就可对其进行修改。在函数中对这个列表所做的任何修改都是永 久性的,这让你能够高效地处理大量的数据。 ## 8.4.2 禁止函数修改列表 可向函数传递列表的副本而不是原件;这样函数所做的任何修改都只影响副本,而丝毫不影响原件。 ``` function_name(list_name[:]) ``` # 8.5 传递任意数量的实参 Python允许函数从调用语句中收集任意数量的实参。 ``` def make_pizza(*toppings): """打印顾客点的所有配料""" print(toppings) make_pizza('pepperoni') make_pizza('mushrooms', 'green peppers', 'extra cheese') ``` 形参名*toppings中的星号让Python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中 ## 8.5.1 结合使用位置实参和任意数量实参 如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最 后。 Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。 例如,如果前面的函数还需要一个表示比萨尺寸的实参,必须将该形参放在形参*toppings的前面: ``` def make_pizza(size, *toppings): """概述要制作的比萨""" print("\nMaking a " + str(size) + "-inch pizza with the following toppings:") for topping in toppings: print("- " + topping) make_pizza(16, 'pepperoni') make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') ``` Python将收到的第一个值存储在形参size中,并将其他的所有值都存储在元组toppings中。 ## 8.5.2 使用任意数量的关键字实参 需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种 情况下,可将函数编写成能够接受任意数量的键—值对——调用语句提供了多少就接受多少。一 个这样的示例是创建用户简介:你知道你将收到有关用户的信息,但不确定会是什么样的信息。 在下面的示例中,函数build_profile()接受名和姓,同时还接受任意数量的关键字实参 ``` def build_profile(first, last, **user_info): """创建一个字典,其中包含我们知道的有关用户的一切""" profile = {} profile['first_name'] = first profile['last_name'] = last #学习对元组循环处理的写法 for key, value in user_info.items(): profile[key] = value return profile user_profile = build_profile('albert', 'einstein', location='princeton', field='physics') print(user_profile) ``` 函数build_profile()的定义要求提供名和姓,同时允许用户根据需要提供任意数量的名称— 值对。形参**user_info中的两个星号让Python创建一个名为user_info的空字典,并将收到的所 有名称—值对都封装到这个字典中。在这个函数中,可以像访问其他字典那样访问user_info中的 名称—值对。 # 8.6 将函数存储在模块中 将函数存储在被称为模块的独立文件中,再将模块导入到主程序中。 import语句允许在当前运行的程序文件中使用模块中的代码。 通过将函数存储在独立的文件中,可隐藏程序代码的细节,将重点放在程序的高层逻辑上。 这还能让你在众多不同的程序中重用函数。将函数存储在独立文件中后,可与其他程序员共享这些文件而不是整个程序。知道如何导入函数还能让你使用其他程序员编写的函数库。 ## 8.6.1 导入整个模块 要让函数是可导入的,得先创建模块。 模块是扩展名为.py的文件,包含要导入到程序中的代码。 **pizza.py** ``` def make_pizza(size, *toppings): """Summarize the pizza we are about to make.""" print("\nMaking a " + str(size) + "-inch pizza with the following toppings:") for topping in toppings: print("- " + topping) make_pizza(16, 'pepperoni') make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') ``` **making_pizzas.py** ``` import pizza as p p.make_pizza(16, 'pepperoni') p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') ``` 代码行import pizza让Python打开文件pizza.py,并将其中的所有函数都复制到这个程序中。你看不到复制的代码,因为这个程序运行时, Python在幕后复制这些代码。 ## 8.6.2 导入特定的函数 **语法** : from module_name import function_name ``` from pizza import make_pizza make_pizza(16, 'pepperoni') make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') ``` ## 8.6.3 使用 as 给函数指定别名 如果要导入的函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名——函数的另一个名称 给函数make_pizza()指定了别名mp() ``` from pizza import make_pizza as mp mp(16, 'pepperoni') mp(12, 'mushrooms', 'green peppers', 'extra cheese') ``` ## 8.6.4 使用 as 给模块指定别名 还可以给模块指定别名。通过给模块指定简短的别名(如给模块pizza指定别名p),让你能够更轻松地调用模块中的函数 ``` import pizza as p p.make_pizza(16, 'pepperoni') p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') ``` ## 8.6.5 导入模块中的所有函数 使用星号(*)运算符可让Python导入模块中的所有函数: ``` from pizza import * make_pizza(16, 'pepperoni') make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') ``` 不推荐这种做法,要么只导入你需要使用的函数,要么导入整个模块并使用句点表示法 # 8.7 函数编写指南 ![](https://img.kancloud.cn/ad/a4/ada4e00828beaceadc36f8269d858d02_414x210.png) 用两个空行将相邻的函数分开