7、函数
- 函数定义方式
使用def关键字定义函数,在圆括号中写明形参,函数定义第一行之后的连续三个引号括出的是函数功能说明,依此可以生成有关程序中的文档,这不是必须的,但是是一个好习惯,能够让别人使用你的代码时,快速知道函数的功能。
在第一行之后利用缩进表明函数的范围。
定义:
def function_name (args):
"""这是函数的文档定义,即功能说明"""
do something
(return something) #可选
调用:
function_name(args) #无返回值
item = function_name(args) #有返回值
- 实参的传递方式
- 位置实参:传递的实参在括号中的位置需要与形参定义的顺序一一对应。
- 关键字实参:传递实参时,传递的是 key = value ,其中key是形参的名字,value是其对应的值。
- 列表和字典:将列表或者字典作为实参传入。
def describe_pet(annimal_type, pet_name):
print(f"{pet_name.title()} is a lovely {annimal_type}!")
#位置实参
describe_pet('cat','lucy')
#关键字实参
describe_pet(pet_name='lucy', annimal_type='cat')
输出:
Lucy is a lovely cat!
Lucy is a lovely cat!
- 为形参指定默认值
通过为形参指定默认值,可以在未给出实参时,自动使用默认值。
使用默认值是,必须现在形参列表中列出没有默认值的形参,再列出有默认值的实参,这样Python依然能欧股正确地解读位置实参。
def describe_pet(annimal_type, pet_name, pet_color = 'white'):
print(f"{pet_name.title()} is a lovely {pet_color} {annimal_type}!")
#缺省实参
describe_pet('cat','lucy')
#全部实参
describe_pet('dog','jim','black')
输出:
Lucy is a lovely white cat!
Jim is a lovely black dog!
- 让实参变成可选的
可以为形参设置空值,然后在程序中判断该形参是否传入了实参,通过这种做法可以达到设置可选参数的作用。
Python将非空字符串解读为true,将空字符串解读为false。特殊值None(表示变量没有值)在条件测试中相当于false。
def describe_pet(annimal_type, pet_name, pet_color = ''):
if(pet_color):
print(f"{pet_name.title()} is a lovely {pet_color} {annimal_type}!")
else:
print(f"{pet_name.title()} is a lovely {annimal_type}!")
#只有姓名和类型的宠物
describe_pet('cat','lucy')
#有姓名、类型、颜色的宠物
describe_pet('dog','jim','black')
输出:
Lucy is a lovely cat!
Jim is a lovely black dog!
- 传递任意数量的实参
有时候,预先不知道函数需要接收多少个实参,Python允许函数从调用语句中收集任意数量的实参。
形参名*args中的*号让Python创建一个名为args的空元组,并将收到的所有值都封装到这个元组中,注意,哪怕只有一个实参,Python也会将其封装到元组中。
def name_of_team_members(*args):
print("\nThe items in args are:",args)
print("The name of my team members are:")
for item in args:
print(item.title())
name_of_team_members('wang','tian')
name_of_team_members('li','zhang','liu')
输出:
The items in args are: ('wang', 'tian')
The name of my team members are:
Wang
Tian
The items in args are: ('li', 'zhang', 'liu')
The name of my team members are:
Li
Zhang
Liu
- 结合使用位置实参和任意数量实参
如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
def describe_pet(annimal_type, pet_name, *args):
print(f"{pet_name.title()} is a lovely {annimal_type}!\nHe has some technics:")
for item in args:
print(item)
describe_pet('dog','jim','swim','jump')
输出:
Jim is a lovely dog!
He has some technics:
swim
jump
- 使用任意数量的关键字实参
有时候,需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种情况下,可将函数编写成能够接收任意数量的额键值对——调用语句提供了多少就接受多少。
形参**args中的两个星号让Python创建一个名为args的空字典,并将收到的所有名称值对都放到这个字典中。
def describe_pet(annimal_type, pet_name, **args):
print(f"{pet_name.title()} is a lovely {annimal_type}!\nHe has some features:")
for k,v in args.items():
print(k,':',v)
describe_pet('dog','jim', color='black',weight='10kg',sport='swim')
输出:
Jim is a lovely dog!
He has some features:
color : black
weight : 10kg
sport : swim
- 列表作为实参传入
在Python中,将列表传递给函数后,函数就可对其进行修改。在函数中对这个列表所做的任何修改都是永久性的,这让我们能够高效的处理大量数据。
有时候,需要禁止函数修改列表。这时可向函数传递列表的副本而非原件。这样,函数所做的任何修改都只影响副本,而原件丝毫不受影响。
虽然向函数传递列表的副本可保留原始列表的内容,但除非有充分的理由,否则还是应该将原始列表传递给函数。这是因为让函数使用现成的列表可避免花时间和内存创建副本,从而提高效率,在处理大型列表时尤其如此。
items = list(range(5))
print(items)
def increase_number(items):
for i in range(len(items)):
items[i] += 1
#传入列表副本
increase_number(items[:])
print(items)
#传入列表
increase_number(items)
print(items)
输出:
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[1, 2, 3, 4, 5]
- 函数的返回值
在函数中,可使用return语句将值返回到调用函数的代码行。返回值让你能够将程序的大部分繁重工作移到函数中去完成,从而简化主程序。
调用返回值的函数时,需要提供一个变量,以便将返回的值赋给它。
函数可返回任何类型的值,包括列表和字典等较复杂的数据结构。
def describe_pet(annimal_type, pet_name):
message = f"{pet_name.title()} is a lovely {annimal_type}!"
return message
message = describe_pet('dog','jim')
print(message)
输出:
Jim is a lovely dog!
- 为函数形参和返回值注明类型
在Python3中提供了一种注释语法,可以为函数的形参和返回值注明类型,但是注意这只是注释,程序在运行的时候不会受到注释的影响,只是为了阅读方便,即使不遵照注明的类型也能正常运行。这个并不是特别重要的东西,但是见了要认识。更多详细见这篇文章。
注释形式:
class Solution:
def arrayPairSum(self, nums: List[int]) -> int:
return sum(sorted(nums)[0::2])
不遵循注释亦可运行:
def fun(x: int) -> str:
return [x]
print(fun('test'))
输出:
['test']
- 将函数存储在模块中
模块:扩展名为.py的文件,包含要导入到程序中的代码。
导入方法:
直接导入模块(调用函数使用 ‘ . '的方式,即句点表示法)
import module
导入模块中某个特定函数
from module import function_1
导入模块中多个特定函数
from module import function_1, function_2, function_3
导入模块中的所有函数(非常不推荐)
from module import *
用as为模块指定别名
import module as m
用as为函数指定别名
from module import function_1 as f1
在指定别名之后,在本文件里就不需要使用原来的模块名或函数名,转而使用这个别名。
在我们引用函数的时候,最佳做法是要么只导入需要使用的函数,要么导入整个模块并使用句点表示法。
- 一些约定
每个函数都应包含简要阐述其功能的注释,该注释应紧跟在函数定义后面,并采用文档字符串格式(三个双引号包含)。
给形参指定默认值时,以及函数调用中的关键字实参,等号两边不要有空格。
所有import语句都应放在程序的开头。
import引用公共库的模块应放在前面,自己的模块放在后面,中间用空行隔开。