python入门基础(9)--函数及模块

函数是带名字的代码块,要执行函数定义的特定任务,可调用该函数。

需要在程序中多次执行同一项任务时,你无需反复编写完成该任务的代码,而只需调用执行该任务的函数,通过使用函数,程序的编写、阅读、测试和修复都将更容易。主程序文件的组织更为有序

一、如何定义一个函数

使用关键字 def 来定义一个函数。

def greeting_user():
    print("Hello!,Welcome to Python World!")   
greeting_user()

如上述代码:第一行定义一个函数greeting_user,第二行为函数的功能,即打印字符串 "Hello!,Welcome to Python World!"

第三行,即调用函数greeting_user,作用就是打印字符串。

1)向函数传递信息

稍作修改,在函数定义 def greeting_user() 的括号内添加 username ,可让函数接受所给定 username 指定的任何值。

这个函数就可以调用给 username 指定一个值,调用 greeting_user() 时,可将一个名字传递给它,如下所示: 

def greeting_user(username):
    print("Hello!,Welcome "+ username.title() + " use Python programing language!")

greeting_user('Bush')
greeting_user('Jack')
greeting_user('Lucy')

代码 greeting_user('Bush') 调用函数 greeting_user() ,并向它提供执行 print 语句所需的信息。这个函数接受你传递给它的名字

 2)实参和形参

前面定义函数 greeting_user() 时,要求给变量 username 指定一个值。调用这个函数并提供这种信息(人名)时,它将打印相应的问候语。
在函数 greeting_user() 的定义中,变量 username 是一个形参函数完成其工作所需的一项信息

在代码 greeting_user('Bush') 中,值 'Bush'、‘Jack’、‘Lucy’ 是一个实参。实参是调用函数时传递给函数的信息,也即这几个字符串,会被传递给形参 username

调用函数时,将要让函数使用的信息放在括号内。在greeting_user('Bush') 中,将实参'Bush' 传递给了函数 greeting_user() ,这个值被存储在形参 username 中。

 二、实参

1)位置实参

由于通常函数中,会存在多个形参,调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此,最简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参。

def my_pet(animal_type, pet_name): 
    print("\nI have a " + animal_type + ".")
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")

my_pet('dog', 'Wangcai')

 上述代码中,my_pet()函数中存在两个形参,即animal_type和pet_name,也就是在调用函数my_pet()时,需要2个参数,即在my_pet('dog', 'Wangcai')中,将‘dog’存入到animal_type中,‘Wangcai’存入到pet_name中,并在my_pet()中的两个print语句中进行调用 。

注意:使用位置实参来调用函数时,如果实参的顺序不正确,结果会出错。

2)关键字实参

关键字实参是传递给函数的名称-值对。直接在实参中将名称和值关联起来,函数传递实参时不会混淆。关键字实参让你无需考虑函数调用中的实参顺序,还清楚地指出了函数调用中各个值的用途。

my_pet(animal_type='dog', pet_name='Wangcai')
my_pet(pet_name='Xiaoqiang',animal_type='cockroach')

函数 my_pet() 还是原来那样,但调用这个函数时,向Python明确地指出了各个实参对应的形参。注意:上述两个形参位置改变,在赋值的情况下,不影响程序运行。

运行结果

I have a dog.
My dog's name is Wangcai.

I have a cockroach.
My cockroach's name is Xiaoqiang.

3)默认值

编写函数时,可给每个形参指定默认值。如果在调用函数中给形参提供了实参,Python将使用指定的实参值;否则,将使用形参的默认值。因此,给形参指定默认值后,可在函数调用中省略相应的实参

def my_new_pet(new_pet_name,new_animal_type='dog'): 
    print("\nI have a " + new_animal_type + ".")
    print("My " + new_animal_type + "'s name is " + new_pet_name.title() + ".")

my_new_pet(new_pet_name='Wangcai')
my_new_pet(new_pet_name='Xiaoqiang')
my_new_pet(new_pet_name='Xiaoqiang',new_animal_type='cockroach')

运行结果:

I have a dog.
My dog's name is Wangcai.

I have a dog.
My dog's name is Xiaoqiang.

I have a cockroach.
My cockroach's name is Xiaoqiang.

 第一、二个my_new_pet()函数调用只给定了两个名字,没有给定动物类型,则函数采用默认类型‘dog’,第三个函数调用给定的new_animal_type='cockroach',则函数中两个打印调用给定的cockroach类型。

实际运行结果:

注意:可混合使用位置实参、关键字实参和默认值,通常有多种等效的函数调用方式,如上述

my_pet(animal_type='dog', pet_name='Wangcai')
my_pet(pet_name='Xiaoqiang',animal_type='cockroach')
my_new_pet(new_pet_name
='Wangcai') my_new_pet(new_pet_name='Xiaoqiang') my_new_pet(new_pet_name='Xiaoqiang',new_animal_type='cockroach')

三 ,函数的返回值
函数可以处理一些数据,并返回一个或一组数值,函数返回的值被称为返回值。在函数中,可使用 return 语句将值返回到调用函数的代码行。返回值能够将程序的大部分繁重工作移到函数中去完成,从而简化主程序

1)返回简单值

def get_full_name(first_name, middle_name, last_name):   #定义一个函数,有三个形参
    full_name = first_name+' '+middle_name+' '+last_name #函数功能,将函数的三个形参进行连接
    return full_name.title()                     #返回值

musician = get_full_name('Bush','lee', 'Alien')  
# 调用返回值的函数时,需要提供一个变量musician,用于存储返回的值
# 通过函数将Bush和Alien连接后,赋值给变量musician
print(musician)

2)传递列表

向函数传递列表很有用,这种列表包含的可能是名字、数字或更复杂的对象(如字典),将列表传递给函数,函数就能直接访问其内容。

def menu_lists(menus):  #定义一个函数,参数为列表
    for menu in menus:   #循环列表
        msg = "The new menus is " + menu.title() + "!"
        print(msg)  #打印列表
        
new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers']
#定义一个列表
menu_lists(new_menus) 
#调用函数menu_lists,并将列表new_menus传递给menu_lists(menus)中的形参menus,并执行函数中的循环

(1)在函数中修改列表
将列表传递给函数后,函数就可对其进行修改。在函数中对这个列表所做的任何修改都是永久性的,这让你能够高效地处理大量的数据。

completed_menus = []  #创建一个名为 completed_menus 的空列表
# 模拟打印每个设计,直到没有未打印的菜单为止
# 打印每个菜单后,都将其移到列表completed_menus中
while new_menus:
    current_menu = new_menus.pop() #pop,从列表new_menus末尾删除一个设计,并存放到变量名current_menu中
    #模拟根据设计制作打印菜单的过程
    print("Printing menu: " + current_menu)
    completed_menus.append(current_menu)     #在列表completed_menus中,逐渐存入变量名current_menu的值

#下列代码打印new_menus   
print(new_menus)  #打印出列表new_menus
    
print("\nThe following menus have been printed:")# 显示打印好的所有菜单
for completed_menu in completed_menus: #for循环,打印出列表completed_menus
    print(completed_menu)

运行结果如下:

Printing menu: Chicken Feet with Pickled Peppers
Printing menu: Spicy fish pieces
Printing menu: Boiled meat
[]

The following menus have been printed:
Chicken Feet with Pickled Peppers
Spicy fish pieces
Boiled meat

 上述代码运行结果:

 

注:代码重组

在(1)函数中修改列表里列举的代码,有许多的重复功能 ,可以重新组织这些代码,编写两个函数,一个函数将负责处理打印菜单的工作,另一个将描写打印了哪些菜单。

#下述先定义两个函数
def print_menus(new_menus, completed_menus):  #定义一个函数将负责处理打印菜单的工作
    while new_menus:  #当new_menus不为空
        current_menu = new_menus.pop()    #弹出 new_menus中最后一个元素,并赋值给变量current_menu   
        #注意    pop()的顺序是反序,也即从最后一个元素开始,到第一个元素结束。
        print("Printing menus: " + current_menu)
        completed_menus.append(current_menu)    #列表completed_models逐渐增加

def show_completed_menus(completed_models):   #定义函数,显示已打印了哪些菜单
    print("\nThe following models have been printed:")
    for completed_model in completed_models: #for循环,打印出数列completed_models中的元素
        print(completed_model)

#定义一个列表,一个空表,再调用上述两个函数。
new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers']
completed_menus = [] #创建一个空表
print_menus(new_menus, completed_menus) #调用第一个函数,打印菜单 
show_completed_menus(completed_menus)   #调用第2个函数,显示已完成菜单

运行结果:

Printing menus: Chicken Feet with Pickled Peppers
Printing menus: Spicy fish pieces
Printing menus: Boiled meat

The following models have been printed:
Chicken Feet with Pickled Peppers
Spicy fish pieces
Boiled meat

 (2)禁止函数修改列表

在程序运行时,可能需要禁止函数修改列表。

编写了一个将这些移到打印好的菜单列表中的函数,可能会做出这样的决定:即便打印所有菜单后,也需要保留原来的未打印的菜单列表,以供备案。

例如,上述列表new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers'],由于使用pop,将所有菜单都移出了new_menus,使得列表new_menus变成了空的,致使原有数据丢失(如上述运行结果第4行显示为[]  )。

为解决此问题,可向函数传递列表的副本;这样函数所做的任何修改都只影响副本,而丝毫不影响原列表。切片表示法 [:] 创建列表的副本 

#禁止函数修改列表
my_menus = ['meat', 'fish pieces', 'Chicken Feet']
print_menus(my_menus[:],completed_menus)

print(my_menus)  #重新打印列表my_menus,

如上述代码,重新定义一个列表my_menus ,调用重组后的函数print_menus,但参数只给定了my_menus[:]和completed_menus,最后重新打印列表my_menus ,检查是否是空列表。

运行结果如下:

Printing menus: Chicken Feet
Printing menus: fish pieces
Printing menus: meat
['meat', 'fish pieces', 'Chicken Feet']

3)传递任意数量的实参

当预先不知道函数需要接受多少个实参时,Python允许函数从调用语句中收集任意数量的实参。函数只有一个形参 *toppings ,但不管调用语句提供了多少实参,这个形参都将它们统统收入囊中

形参名 *toppings 中的星号让Python创建一个名为 toppings 的空元组,并将收到的所有值都封装到这个元组中

def make_menus(*toppings): 
    print("\nMaking a menus with the following toppings:")
    for topping in toppings:
        print("- " + topping)

make_menus('fish')
make_menus('meat', 'fish', 'beef')

运行如下:

Making a menus with the following toppings:
- fish

Making a menus with the following toppings:
- meat
- fish
- beef

(1)结合使用位置实参和任意数量实参 

在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中

def make_menus(size,*toppings): 
    print("\nMaking a "+str(size)+" kilogram menus with the following toppings:")
    for topping in toppings:
        print("- " + topping)

make_menus(2,'fish')
make_menus(6,'meat', 'fish', 'beef')

运行结果如下:

Making a 2 kilogram menus with the following toppings:
- fish

Making a 6 kilogram menus with the following toppings:
- meat
- fish
- beef

(2)使用任意数量的关键字实参

 

def get_person_info(given_name, family_name,**user_info):   #定义一个函数,有三个形参
    person_info={}  #定义一个person_info
    person_info['first_name']=family_name #字典里的第一个key为first_name,赋值为形参中的given_name
    person_info['last_name']=given_name #字典里的第二个key为last_name,赋值为形参中的family_name
    
    for key,value in user_info.items():
        person_info[key]=value
    return person_info

user_info = get_person_info('albert','einstein',location='princetion',field = 'physics')     
print(user_info)          

运行结果如下:

{'first_name': 'einstein', 'last_name': 'albert', 'location': 'princetion', 'field': 'physics'}

4)将函数存储在模块中

函数的优点:

一,可将代码块与主程序分离。通过给函数指定描述性名称,让主程序容易理解得多。

二、将函数存储在被称为模块的独立文件中,再将模块导入到主程序中。import 语句允许在当前运行的程序文件中使用模块中的代码。
通过将函数存储在独立的文件中,可隐藏程序代码的细节,将重点放在程序的高层逻辑上,能让你在不同的程序中重用函数。
函数存储在独立文件中后,可与其他程序员共享这些文件而不是整个程序。知道如何导入函数还能让你使用其他程序员编写的函数库

1)导入整个模块

让函数是可导入的,创建模块。模块是扩展名为.py的文件,包含要导入到程序中的代码。如下图中的创建一个包含4个不同函数的 function 的模块

在mainframe中调用模块function及其中的函数

import function   #导入模块function

new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers']
completed_menus = [] #创建一个空表
function.print_menus(new_menus, completed_menus) #调用模块function中的函数print_menus 
function.show_completed_menus(completed_menus)   #调用模块function中的函数show_completed_menus
#禁止函数修改列表
my_menus = ['meat', 'fish pieces', 'Chicken Feet']
function.print_menus(my_menus[:],completed_menus)#调用模块function中的函数print_menus


function.make_menus(2,'fish')
function.make_menus(6,'meat', 'fish', 'beef')

user_info =function.get_person_info('albert','einstein',location='princetion',field = 'physics')
#调用模块function中的get_person_info函数     
print(user_info)          

2)导入特定的函数

from function import print_menus,show_completed_menus #直接导入某模块中的特定函数,

new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers']
completed_menus = [] #创建一个空表
print_menus(new_menus, completed_menus) #调用函数print_menus 
show_completed_menus(completed_menus)   #调用函数show_completed_menus

3) 使用 as 给模块指定别名

导入的函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名,类似于外号,在引用 的过程中,就相对比较方便

import function as func #给function指定一个短的名称func

new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers']
completed_menus = [] #创建一个空表
func.print_menus(new_menus, completed_menus) #调用函数print_menus 
func.show_completed_menus(completed_menus)   #调用函数show_completed_menus

as 除了给模块指定别名,也可以给模块中的函数指定别名:

from function import  print_menus  as p_m
from function import  show_completed_menus as s_m

new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers']
completed_menus = [] #创建一个空表
p_m(new_menus, completed_menus) #调用函数print_menus 
s_m(completed_menus)   #调用函数show_completed_menus

4)导入模块中的所有函数

from function import  *

new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers']
completed_menus = [] #创建一个空表
print_menus(new_menus, completed_menus) #调用函数print_menus 
show_completed_menus(completed_menus)   #调用函数show_completed_menus

 

注意区别:(1)在导入模块时,使用函数用法:function.print_menus(new_menus, completed_menus)

                 (2) 导入特定的函数时,使用函数用法:print_menus(new_menus, completed_menus)

                 (3)使用模块的别名时,使用函数用法:func.print_menus(new_menus, completed_menus)

import 开头导入的模块,在使用的时候需要带上模块的名称或别名(  as 后面名称)

from  model  import *  这种类型的则不需要,可以直接调用函数。

posted @ 2022-04-18 22:42  PursuitingPeak  阅读(324)  评论(0编辑  收藏  举报