Python学习日记 Day9函数基础2
今天是2020年2月17日,晴,1~9℃
这几天的天气都挺好,就是可惜自己不敢出门。
一、传递列表
将列表作为实参传递给函数,能提高处理列表的效率。
def hello(names):
'''简单问好'''
for name in names:
print("Hello, " + name + "!")
names = ["Micheal","Bulk","Peter"]
hello(names)
'''
Output:
Hello, Micheal!
Hello, Bulk!
Hello, Peter!
'''
1、在函数中修改列表
将列表传递给函数后,函数就可以对其进行修改。在函数中对这个列表的修改也会永久影响中传入的实参列表。
def move_house(community_1,community_2):
'''社区1中成员搬家'''
while community_1:
person = community_1.pop()
print(person + " has moved to community_2!")
community_2.append(person)
community_1 = ["Micheal","Bulk","Peter"]
community_2 = []
move_house(community_1,community_2)
'''
Output:
Peter has moved to community_2!
Bulk has moved to community_2!
Micheal has moved to community_2!
'''
2、禁止函数修改列表
有时我们希望列表传递给函数后,函数内对列表的修改不会影响到原本的列表,这里可以将列表的副本传递给函数。如:
def add_one(numbers):
'''数值列表中所有数加一'''
for i in range(0,5):
numbers[i] += 1
return numbers
numbers_1 = [1,2,3,4,5]
numbers_2 = add_one(numbers_1[:])
print(numbers_1) #Output:[1, 2, 3, 4, 5]
print(numbers_2) #Output:[2, 3, 4, 5, 6]
对于简单数据类型,如数值等,实参传递给形参的过程是值传递,函数内的操作不会影响原变量。
def add_one(number):
number += 1
return number
number_1 = 1
number_2 = add_one(number_1)
print(number_1) #Output:1
print(number_2) #Output:2
对于复杂数据类型,实参传递给形参的过程和赋值过程类似,都是先为新的变量名分配一个新的空间,再将变量名与实参所对应的对象绑定。因此,在函数内的操作会影响原对象。
若对函数传递一个副本实参,则新的变量(形参)会绑定在该副本上,也就不会对原对象产生影响。
此外,若在函数中存在对形参的赋值行为,也会导致形参所绑定的对象发生变化,也不会对原对象产生影响。
例如试图添加swap函数:
def swap(list_1,list_2):
t = list_1
list_1 = list_2
list_2 = t
list_1 = [1]
list_2 = [2]
swap(list_1,list_2)
print(list_1) #Output:[1]
print(list_2) #Output:[2]
此函数预期达到交换列表的目的。但实际上,函数内列表的交换只是使形参list_1和list_2绑定的对象做了交换,而不改变实参绑定的对象。当函数外访问这两个列表时,会发现它们并没有交换。
二、传递任意数量的实参
有时预先不知道需要的参数个数,这是应使用任意数量实参。
def print_all(*numbers):
'''打印所有数字'''
print(numbers)
print_all(1,2,3) #Output:(1, 2, 3)
print_all(1,1,2,3,5,8) #Output:(1, 1, 2, 3, 5, 8)
由输出结果可以发现,形参 *numbers 会创建一个空元组,并将所有传递给函数的实参都添加进该元组中。也由此我们可以使用 for 循环遍历该元组。
def print_all(*numbers):
'''打印所有数字'''
for number in numbers:
print(number)
print_all(1,1,2,3,5,8)
'''
Output:
1
1
2
3
5
8
'''
1、结合使用位置实参、关键字实参和任意数量实参
若想接受不同类型的实参,必须在定义中将接受任意实参的形参放在最后,优先匹配位置实参和关键字实参。
def print_all_between(first,last,*numbers):
'''输出所有在first和last之间的数字'''
i = 0
for number in numbers:
if i >= first and i < last:
print(number)
i += 1
print_all_betwenn(2,5,1,1,2,3,5,8,13)
'''
Output:
2
3
5
'''
当然,例中前两项实参也可以用关键字实参指定。
2、使用任意数量的关键字实参
预先不知道将会传递的信息时,需要使用任意数量的关键字实参。
def print_person(**person_info):
'''打印人物信息'''
print(person_info)
print_person(name = 'Micheal',age = '18',gender = "male") #Output:{'name': 'Micheal', 'age': '18', 'gender': 'male'}
由输出可以发现,形参 **person_info 将创建一个字典,并将所有关键字实参以键值对的形式存入字典中。因此,可用 for 循环遍历。
def print_person(**person_info):
'''打印人物信息'''
for key,value in person_info.items():
print(key + " : " + value)
print_person(name = 'Micheal',age = '18',gender = "male")
'''
Output:
name : Micheal
age : 18
gender : male
'''
三、将函数存入模块
函数的优点之一就是能将主程序与代码块分离。可以将函数存入称为模块的独立文件中,再将模块导入主程序。
1、创建模块
新建一个.py文件,在该文件内写入函数。
#hello.py
def hello_world():
'''hello world'''
print("Hello World!")
这就是一个简单的模块。
2、导入模块
导入模块有多种办法,可以按不同项目的需求使用。
●导入整个模块
使用import关键字和模块文件名,即可导入整个模块。
#main.py
import hello #import module_name
hello.hello_world()
以这种方法导入后,使用模块内的内容需要添加模块名,形式为 module_name.func_name 。
● 导入特定的函数
使用 from 关键字可以导入特定的函数。
#main.py
from hello import hello_world #from module name import func_name
hello_world()
以这种方式导入后,导入的函数不再需要加模块名。
若要导入多个函数,则不同函数名之间以逗号分隔。
● 给函数指定别名
为避免命名冲突,可以在导入函数时用 as 关键字为函数指定别名。
#main.py
from hello import hello_world as hw #from module_name import func_name as new_name
hw()
● 给函数指定别名
为比较简单的使用模块内容,也可以为函数指定别名。
#main.py
import hello as h #import module_name as new_name
h.hello_world()
指定别名后,原有的函数名/模块名不能再使用。
● 导入所有函数
使用 * 可以导入模块中所有函数,且无需使用模块名使用。
#main.py
from hello import * #from module_name import *
hello_world()
这种方式虽然可以省略模块名,但可能导致命名冲突,造成错误。
书上建议的最佳做法是,要么导入需要的函数,要么导入模块使用句点表示法。
四、函数编写规范
1、应给函数指定描述性名称,并只使用小写字母和下划线。
2、每个函数后都应包含简要阐述功能的注释(以文档字符串的形式)。
3、给形参指定默认值或使用关键字实参时,等号两边不要加空格。
4、PEP-8建议代码行不超过79个字符。如果形参很多,应在左括号后换行并空出两个Tab。
5、如果程序或模块包含多个函数,可使用两个空行将其分隔开。
6、所有的import语句都应放在文件开头,除非开头使用了注释来描述整个程序。
上一篇: hdu1698Just a Hook