一、函数
函数是带名字的代码块,用于完成具体的工作,函数让你的程序变得更加容易阅读和测试,并且一次写好,多次使用
1.创建函数 : 定义函数, 创建函数 关键字def,调用函数,函数名()
def greet_user(): #定义
'''显示简单的问候语'''#函数文档
print("helllo!")#函数体
greet_user()#调用函数
helllo!
#向函数传递信息
def greet_user(username): #定义
'''显示简单的问候语'''
print("hello "+username+' .')#函数体
greet_user('mary')#调用函数
hello mary .
2.实参和形参 实参是定义函数处,函数完成其工作所需要的一项信息,是一个位置,一个变量,如上面的username 实参是调用函数时传递给函数的信息如上面的mary 将实参mary传递给函数greet_user(),这个值被存在形参username中
#传递实参,有很多方法,位置实参,关键字实参,还可指定默认值 这几种方法可以混合使用
#位置实参,顺序很重要,实参和形参一一位置对应
def describe_pet(animal_type,pet_name):#定义一个函数描述宠物,有两个形参,类型和名字
'''显示宠物的信息'''
print("i have a "+animal_type+" .")
print('my '+animal_type+" 's name is "+pet_name.title())
describe_pet("dog","gou")
describe_pet("cat","mao")#可以多次调用
describe_pet("pig","zhu")
i have a dog .
my dog 's name is Gou
i have a cat .
my cat 's name is Mao
i have a pig .
my pig 's name is Zhu
#关键字参数,不在乎位置,直接在实参中将名字和值对应起来,就是在实参中给形参一个值
def describe_pet(animal_type,pet_name):#定义一个函数描述宠物,有两个形参,类型和名字
'''显示宠物的信息'''
print("i have a "+animal_type+" .")
print('my '+animal_type+" 's name is "+pet_name.title())
describe_pet(animal_type="dog",pet_name='gou')#注意,使用关键字实参时,务必准确指出函数定义中的形参名,等号两边不要有空格
describe_pet(pet_name='gou',animal_type="dog")#不在乎顺序
i have a dog .
my dog 's name is Gou
i have a dog .
my dog 's name is Gou
#默认值。在编写函数时,可以给每个形参一个默认值,这样在调用函数时,如果不指定实参,函数就会给这个形参默认值
def describe_pet(pet_name,animal_type="dog"):#定义一个函数描述宠物,有两个形参,类型和名字,给类型默认值dog,注意给形参指定默认值时,等号两边不要有空格
'''显示宠物的信息'''
print("i have a "+animal_type+" .")
print('my '+animal_type+" 's name is "+pet_name.title())
describe_pet("gou")# 注意,在使用默认值时,形参一定要先列出没有默认值的形参,在列出有默认值的
3.返回值,用return语句,将值返回到函数调用的地方
#返回简单值
def get_formatted_name(first_name,last_name):
'''返回整洁的姓名'''
full_name=first_name+" "+last_name
return full_name.title()
programmer=get_formatted_name("xiao","xioahui")#调用有返回值的函数时,需要提供一个变量,用来存储返回的值
print(programmer)
Xiao Xioahui
#让实参变成可选的,这样可以处理不同的情形,确保函数调用尽可能简单
def get_formatted_name(first_name,last_name,mid_name=''):#利用这个空字符串来让实参可变,但是必须保证他是最后一个参数
'''返回整洁的姓名'''
if mid_name:
full_name=first_name+" "+mid_name+" "+last_name
else:
full_name=first_name+" "+last_name
return full_name.title()
programmer=get_formatted_name("xiao","xiao","hui")#传两个三个参数都可以
print(programmer)
programmer=get_formatted_name("xiao","xiao")
print(programmer)
Xiao Hui Xiao
Xiao Xiao
def get_formatted_name(first_name,last_name,mid_name='',middle_name=''):#利用这个空字符串来让实参可变
if mid_name and middle_name:
full_name=first_name+" "+mid_name+middle_name+" "+last_name
else:
full_name=first_name+" "+last_name
return full_name.title()
programmer=get_formatted_name("xiao","xiao","hui","hui")#传两个三个参数都可以
print(programmer)
programmer=get_formatted_name("xiao","xiao")
print(programmer)这种利用两个空字符串的为什么不行,还不清楚,以后再看
#返回字典
def build_person(first_name,last_name,age=''):
person={"first":first_name,"last":last_name}
if age:
person["age"]=age
return person
programer=build_person("xiao","xioahui",18)
print(programer)
{‘first’: ‘xiao’, ‘last’: ‘xioahui’, ‘age’: 18}
#结合函数和while循环
def get_formatted_name(first_name,last_name):
'''返回整洁的姓名'''
full_name=first_name+" "+last_name
return full_name.title()
while True:
print("please tell us you name?\nyou can enter a 'q' to finish !")
f_name=input("first_name: ")
if f_name == 'q':
break
l_name=input("last_name: ")
if l_name == 'q':
break
programmer=get_formatted_name(f_name,l_name) #这两句仍然在循环体内
print("hello,"+programmer )
please tell us you name?
you can enter a ‘q’ to finish !
first_name: xiao
last_name: xiaohui
hello,Xiao Xiaohui
please tell us you name?
you can enter a ‘q’ to finish !
first_name: q
5.传递列表和字典
#传递列表
def greet_users(names): #names是一个列表,里面元素比较多
for name in names: #对列表里面的每个元素进行问候
print("hello,"+name.title()+"!")
user_names=['mary','jack','lili']
greet_users(user_names)
hello,Mary!
hello,Jack!
hello,Lili!
#在函数中修改列表
#3D打印公司,需要打印的存在一个列表中,打印好的放在另一个列表中
#定义两个函数,一个负责处理打印设计,第二个函数负责概述打印了那些设计
def print_models(unprinted_designs,completed_models):
'''模拟打印每个设计,直到没有设计可以打印为止,
打印每个设计之后将它移到completed_models中'''
while unprinted_designs:
current_printed=unprinted_designs.pop()
print("printing model: "+current_printed)#模拟打印过程
#completed_models=current_printed,错误,列表不可以这样扩充
completed_models.append(current_printed)
def show_complete_models(completed_models):
print("the following models have been printed : ")
for completed_model in completed_models:
print(completed_model)
unprinted_designs = ['case','mouse','robot']
completed_models=[]
print_models(unprinted_designs,completed_models)
show_complete_models(completed_models)
print(unprinted_designs)
printing model: robot
printing model: mouse
printing model: case
the following models have been printed :
robot
mouse
case
[]
#禁止函数修改列表,可以将列表的副本传递给函数,这样函数的操作就不会改变原始的列表
def print_models(unprinted_designs,completed_models):
'''模拟打印每个设计,直到没有设计可以打印为止,
打印每个设计之后将它移到completed_models中'''
while unprinted_designs:
current_printed=unprinted_designs.pop()
print("printing model: "+current_printed)#模拟打印过程
#completed_models=current_printed,错误,列表不可以这样扩充
completed_models.append(current_printed)
def show_complete_models(completed_models):
print("the following models have been printed : ")
for completed_model in completed_models:
print(completed_model)
unprinted_designs = ['case','mouse','robot']
completed_models=[]
print_models(unprinted_designs[:],completed_models)
show_complete_models(completed_models)
print(unprinted_designs)
printing model: robot
printing model: mouse
printing model: case
the following models have been printed :
robot
mouse
case
[‘case’, ‘mouse’, ‘robot’]
5.传递任意数量的实参(*收集参数),形参可以接受任意数量的实参
def make_pizza(*toppings): # 星号是将形参接收到的实参全部封装到一个元组中,后面学习**是封装到字典中
print(toppings)
make_pizza("onion")
make_pizza("onion","cheeze","mushroom")
(‘onion’,)
(‘onion’, ‘cheeze’, ‘mushroom’)
#结合使用位置实参和任意数量的实参
def make_pizza(size,*toppings): #python将收到的第一个值存在位置形参中其他值存在元组toppings中
print("making a "+str(size)+"-inch pizza with the following topping :")
for topping in toppings:#打印元组toppings
print(topping)
make_pizza(16,"onion","cheeze","mushroom"
making a 16-inch pizza with the following topping :
onion
cheeze
mushroom
#使用任意数量的关键字实参 用**
def build_profile(first,last,**usre_info):#**usre_info 意思是创建一个空字典,并将收到的键值对存进来
profile={} #创建一个字典里面将存储我们所知道的一切
profile['first name']=first
profile['last name']=last
for k,v in usre_info.items():
profile[k]=v
return profile
q=build_profile("xiao","xiaohui",age=18,career="programmer")#键值对的格式要注意,键不用加引号
print(q)
{‘first name’: ‘xiao’, ‘last name’: ‘xiaohui’, ‘age’: 18, ‘career’: ‘programmer’}
6.将函数存在模块中 import
函数的优点之一就是它们可以将代码块与主程序分离使得程序简洁,你还可以进一步将函数存储在独立的文件中,隐藏函数的细节,将重点放在程序的更高逻辑上,即将函数存在模块中
(1)导入整个模块
要想让函数导入模块中,首先创建模块,模块的扩展名是.py文件,包含要导入到程序中的代码。
下面创建一个包含函数make_pizza()的模块,取名pizza.py
def make_pizza(size,*toppings):
print("making a "+str(size)+"-inch pizza with the following topping :")
for topping in toppings:#打印元组toppings
print("-"+topping)
接下来,我们在pizza.py所在的目录下在创建一个making_pizza.py 的文件,这个文件导入刚刚创建的模块,在再调用函数make_pizza()两次
import pizza #导入模块pizza就可以使用pizza中定义的函数,使用方法如下
pizza.make_pizza(16,"nushroom")
pizza.make_pizza(18,"nushroom","cheeze","green")
导入结果
making a 16-inch pizza with the following topping :
-nushroom
making a 18-inch pizza with the following topping :
-nushroom
-cheeze
-gree
综上,导入方法,只需要编写一条inport语句,并在其中指定导入的模块名,就可以在程序中使用该模块的所有函数,用以下方法使用任一函数:modul_name.function()
(2)如果只想导入一些特定的函数:from modul_name import function_name,通过逗号分隔函数名,这样在使用的时候,直接调用函数即可
from pizza import make_pizza
make_pizza(16,"nushroom")
make_pizza(18,"nushroom","cheeze","green")
(3)使用as给函数指定别名
from modul_name import function_name as fu,
from pizza import make_pizza as mp
mp(16,"nushroom")
mp(18,"nushroom","cheeze","green")
(4)使用as给模块指定别名
import module_name as mn
import pizza as p
p.make_pizza(16,"nushroom")
p.make_pizza(18,"nushroom","cheeze","green")
(5)导入模块中所有函数
from module_name import *,然后就可以直接调用该模块的所有函数,这种方法最好不要用,了解即可
综上,最佳做法是,要么只导入你需要的函数,要么导入整个模块,并使用句点表示法,这可以让代码更加清晰,更容易阅读和理解