函数

函数是带名字的代码块,用于完成具体的工作。
通过使用的函数,程序的编写、阅读、测试和修复都将更容易。
本节内容包括函数的定义、向函数传递参数、函数的返回值和模块的导入。

- 函数的定义

##---def function
def greet_user():
	print("Hello!")
##---use function
greet_user()

函数的定义使用关键字def,函数名后面的括号和冒号都是必须的。
使用的时候直接调用就OK了,和C++一样。

- 向函数传递参数

向函数传递参数涉及到形参和实参的概念,简单的理解在函数定义中的输入变量是形参,而在函数调用过程中的输入变量是实参,实参可以传递给形参,反之不可以。
Python向函数传递实参分两种方式:位置实参和关键字实参。
位置实参:要求实参顺序和形参顺序保持一致【通过位置来区别各个参数】
关键字实参:每个实参都由变量名和值组成【通过关键字区别各个参数】

位置实参的例子:

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

describe_pet("hamster",'Harry')
describe_pet("dog",'Lele')

python函数实现值传递 python中如何向函数传递参数_默认值


关键字实参的例子:

def describe_pet(animal_type,pet_name):
	print("\nI have a "+animal_type+".")
	print("My "+animal_type+"'s name is "+pet_name+".")
	
describe_pet(animal_type="hamster",pet_name='Harry')
describe_pet(pet_name='Harry',animal_type="hamster")

python函数实现值传递 python中如何向函数传递参数_ci_02


位置实参的顺序很重要,而关键字实参的顺序却无关紧要。

默认值

编写函数时,可以给每个形参指定默认值。
给形参指定默认值后,可在函数调用中省略相应的实参。

def describe_pet(animal_type,pet_name='harry'):
	print("\nI have a "+animal_type+".")
	print("My "+animal_type+"'s name is "+pet_name+".")
describe_pet("hamster")
describe_pet(pet_name='Peter',animal_type="hamster")

这里需要注意的点是如果采用位置实参的方法,指定默认值的形参需要放在后面。

python函数实现值传递 python中如何向函数传递参数_python函数实现值传递_03


可以混合使用位置实参、关键词实参和默认值,因此有多种等效的函数调用方式。

传递任意数量的实参
有时候,预先不知道函数需要接受多少个实参,python允许函数从调用语句中收集任意数量的实参。

def make_pizza(*toppings):
	print(toppings)
make_pizza('pepperoni')
make_pizza('mushrooms','greens peppers','extra cheese')

python函数实现值传递 python中如何向函数传递参数_ci_04


形参名*toppings中的星号让python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中。【总觉得这是个指针,这里不明白机理】

结合使用位置实参和任意数量实参
如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python会先匹配位置实参和关键字实参,然后将余下的实参收集到最后一个形参中。

def make_pizza(size,*toppings):
	print("\nMaking a "+str(size)+"-inch pizza with following toppings:")
	for topping in toppings:
		print("-"+topping)
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','greens peppers','extra cheese')

python函数实现值传递 python中如何向函数传递参数_传递参数_05


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

有时候需要接受任意数量的实参,但是预先不知道传递给函数的会是什么样的信息。在这种情况下,可将函数编写成能够接受任意数量的键值对。

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='princton',field='physics')
print(user_profile)

形参**user_info的两个星号让python创建一个名为user_info的空字典,并将收到的所有键值对都封装到这个字典中。

向函数传递列表
向函数传递列表是很有用的。

def greet_users(names):
	for name in names:
		msg="Hello,"+name.title()+"!"
		print(msg)
usernames=['haang','ty','margot']
greet_users(usernames)

python函数实现值传递 python中如何向函数传递参数_ci_06


在函数中修改列表

def print_models(unprinted_designs,completed_models):
	while unprinted_designs:
		current_design=unprinted_designs.pop()
		print("Printing model: "+current_design)
		completed_models.append(current_design)
def show_completed_models(completed_models):
	print("\nThe following models have been printed: ")
	for completed_model in completed_models:
		print(completed_model)

unprinted_designs=['iphone case','robot','doedsad']
completed_models=[]

print_models(unprinted_designs,completed_models)
show_completed_models(completed_models)

编写了两个函数,每个负责一件具体的工作。

第一个函数将负责处理打印设计的工作,另一个将概述打印了哪些设计。

python函数实现值传递 python中如何向函数传递参数_ci_07


禁止函数修改列表

禁止函数修改列表,只需要将列表的副本传递给函数。

切片法[:]表示创建列表的副本。

def print_models(unprinted_designs,completed_models):
	while unprinted_designs:
		current_design=unprinted_designs.pop()
		print("Printing model: "+current_design)
		completed_models.append(current_design)
def show_completed_models(completed_models):
	print("\nThe following models have been printed: ")
	for completed_model in completed_models:
		print(completed_model)

unprinted_designs=['iphone case','robot','doedsad']
completed_models=[]
print(unprinted_designs)
print_models(unprinted_designs[:],completed_models)
print(unprinted_designs)
print_models(unprinted_designs,completed_models)
print(unprinted_designs)

python函数实现值传递 python中如何向函数传递参数_ci_08


向函数传递列表的副本可以保留原始内容,但除非有充分的的理由这么做,否则还是应该把原始列表传递给函数,因为让函数使用现成列表可以避免花费时间和内存创建副本而提高效率,尤其在处理大型列表时。

- 函数的返回值

函数处理数据后往往需要返回数据,return可以将值返回到调用函数的代码行。

def get_formatted_name(first_name,last_name):
	full_name=first_name+" "+last_name
	return full_name
	
musician=get_formatted_name('jim','henrix')
print(musician)

调用返回值时需要提供一个变量用来存储返回的值。
函数可以返回任何类型的值,包括列表和字典等较复杂的数据结构。
返回字典的例子

def build_person(first_name,last_name):
	person={'first':first_name,'last':last_name}
	return person
	
musician=build_person('jim','henrix')
print(musician)

python函数实现值传递 python中如何向函数传递参数_python函数实现值传递_09

模块的导入

函数的优点之一是可以将代码块和主程序分离,通过给函数指定描述性名称可以让主程序容易理解得多。更进一步地可以将函数存储在被称为模块 的独立文件中,再将模块导入到主程序中。
导入整个模块
模块时扩展名为.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)

在另一个文件中导入该模块

import pizza #import module_name
pizza.make_pizza(16,'pepperoni')#module_name.function_name()
pizza.make_pizza(12,'mushrooms','greens peppers','extra cheese')

import pizza as p #another name
p.make_pizza(16,'pepperoni')#module_name.function_name()
p.make_pizza(12,'mushrooms','greens peppers','extra cheese')

#import all function
from pizza import * 
make_pizza(16,'pepperoni')#function_name()
make_pizza(12,'mushrooms','greens peppers','extra cheese')

这是导入模块中所有函数的方法,其中第二种指定别名的方式比较常见,而第三种容易和本文件中的函数重名,不太建议使用。

导入特定函数的方法

### import function from module
from pizza import make_pizza
make_pizza(16,'pepperoni')#function_name()
make_pizza(12,'mushrooms','greens peppers','extra cheese')

### import function from module
from pizza import make_pizza as mp #another name
mp(16,'pepperoni')#function_name()
mp(12,'mushrooms','greens peppers','extra cheese')

使用as给函数或模块指定别名,指定简洁的别名既可以避免重名,又比较简洁。

在编写函数时,应给函数指定描述性名称,应包含简要阐述其功能的注释。
此外在给形参指定默认值时,等号两边不要有空格。