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 *  这种类型的则不需要,可以直接调用函数。

标签: python

添加新评论