1 概述

函数时带名字的代码块,用于完成具体的工作。要执行函数定义的特定任务,可调用该函数。当需要在程序中多次执行同一个任务时,无须反复编写完成该任务的代码,只需要调用执行该任务的函数。

2 定义函数

def hello():
    print('hello')
hello()

以上示例演示了最简单的函数结构。第一行使用关键字def声明一个函数,并定义函数名(hello),还可以在()内指出函数为完成册好难过任务需要哪些信息。最后,定义以冒号结尾。

2.1 向函数传递信息

定义函数时,在括号内添加信息。那么在调用该函数时同样需要输入信息。

def hello(name):
    print(f'Hello {name}')
message = input('Enter your name: ')
hello(message)

2.2 实参和形参

在上面函数中,变量 name 是一个形参,即函数完成任务需要的信息。在调用hello(message)中,message 是一个实参,即调用函数时传递给函数的信息。

3 传递实参

函数定义中可能包含多个形参,因此调用函数时也可能包含多个实参。向函数传递实参的方式很多:既可以使用位置实参,这要求实参的顺序和形参的顺序相同;也可是使用关键字实参,其中每个实参都是由变量名和值组成;还可以使用列表和字典。

3.1 位置实参

在调用函数时,Python必须将函数调用中的每个实参关联到函数定义中的一个形参。最简单的方式是基于实参的顺序进行关联。这种方式关联的实参称为位置实参。

def classstudent_info(name,age):
    print(f"这位同学的名字是:{name}")
    print(f"这位同学的年龄是:{age}")
classstudent_info('zhangsan',17)

3.2 关键字实参

关键字实参是传递给函数的名值对。这样会直接在实参中将名称和值关联起来,因此向函数从传递实参时就不会混淆。关键字实参无须考虑函数调用中的实参顺序。

def person_info(name,age):
    print(name)
    print(age)
person_info(age = 20,name = 'zhangsan')

3.3 默认值

在编写函数时,可以给每个形参指定默认值。如果在调用函数中给形参提供了实参,那么将使用指定的实参值;否则,将使用形参的默认值。

def class_info(name,classname='三年二班'):
    print(name,classname)
class_info('zhangsan')

4 返回值

函数并非总是直接输出,还可以处理一些数据,并返回一个或一组值,函数返回的数据称为返回值。在函数中,可以使用return 语句将值返回到调用函数的位置。返回值能将程序大部分繁重工作转移到函数中完成,从而简化主程序代码。

4.1 返回简单的值

def cal_(x,y,opear):
    if opear == 'add':
        return x + y
    elif opear == 'sub':
        return x - y
    elif opear == 'mul':
        return x * y
    elif opear == 'div' and y != 0:
        return x / y
    return None


print(cal_(1,2,'add'))
print(cal_(1,2,'sub'))
print(cal_(1,2,'mul'))
print(cal_(1,2,'div'))

4.2 返回字典

函数可以返回任何类型的值,包括列表和字典。

def person(name,age = 18,gender = 'male'):
    student = {'name': name, 'age': age, 'gender': gender}
    return student
print(person('john',19,'male'))
print(person('john',gender = 'female'))

4.3 结合使用函数和while循环

def person(name,age = 18,gender = 'male'):
    student = {'name': name, 'age': age, 'gender': gender}
    return student
while True:
    name = input('请输入姓名: ')
    age = int(input('请输入年龄: '))
    gender = input('请输入性别: ')
    person(name,age,gender)
    if name == 'quit':
        break
    elif age == 10:
        break
    elif gender == None:
        break
    print(person(name,age,gender))

4.4 传递列表

实际开发中,有时需要向函数传递列表,可能是名字列表、数值列表或更复杂的对象列表。将列表传递给函数后,函数就能直接访问其内容。假设有一个用户列表,要向每个用户发出问候。

def persons_hello(persons):
    for person in persons:
        print(f"hello, {person}")
persons = ['zhangsan', 'lisi', 'jason']
persons_hello(persons)

4.4.1 在函数中修改列表

将列表传递给函数后,函数就可以对其进行修改。在函数中对这个列表的修改是永久的。

def update_colour(colours):
    colours_new = []
    for colour in colours:
        if colour == 'blue':
            colours.remove(colour)
            colours_new.append(colour)
        elif colour == 'green':
            colours.remove(colour)
            colours_new.append(colour)
    print(f"原列表的内容: {colours}")
    print(f"新列表的内容: {colours_new}")
    return colours_new
colours = ['blue','black','green']
update_colour(colours)

5 传递任意数值的实参

在实际开发中,有时无法确认函数需要多少个实参,可以使用星号加形参名表示,如*params

def get_names(*names):
    for name in names:
        print(name)
get_names('zhangsan')
get_names('zhangsan', 'liu')

*names 中的星号让Python创建一个名为names的元组,该元组包含函数收到的所有值。

5.1 结合使用位置实参和任意数量的实参

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

def classes(class_name,*names):
    print(f"班级是: {class_name}")
    print(f"该班的同学是:")
    for name in names:
        print(name)
classes('三年二班','zhangsan','lisi','wangwu')

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

实际开发中,可能会遇到以下情况:需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。这种情况下,可将函数编写成能够接受任意数量的键值对——调用语句提供了多少就接受多少。使用两个星号加上变量名。如 **params

def person_info(name,age,**socre):
    print(f"姓名是: {name},年龄是: {age},考试成绩如下:")
    for key,value in socre.items():
        print(f"{key}: {value}")
person_info('张三',22,C = 100,JAVA = 99,PYTHON = 99)

6 将函数存储在模块中

使用函数的优点之一是可将代码块与主程序分离。通过给函数指定描述性名称,能让程序容易理解。现在更近一步,将函数存储在称为模块的独立文件中,再将模块导入主程序。import语句可以在当前运行的程序文件中使用模块中的代码。通过将函数存储在独立的文件中,可隐藏程序代码的细节,将重点放在程序的高层逻辑上。

6.1 导入整个模块

首先创建模块。模块同样是.py格式的文件,包含要导入程序的代码。下面创建一个包含加减乘除的方法的模块。创建cal01.py文件。

def cal(num1,num2,opera):
    if opera == "+":
        return num1 + num2
    elif opera == "-":
        return num1 - num2
    elif opera == "*":
        return num1 * num2
    elif opera == "/" and num2 != 0:
        return num1 / num2

在主程序页面导入该文件后,调用。

import cal01
result = cal01.cal(1,2,"+")
print(f"加法运算: {result}")
result = cal01.cal(2,4,'-')
print(f"减法运算: {result}")
result = cal01.cal(2,4,'*')
print(f"乘法运算: {result}")
result = cal01.cal(2,4,'/')
print(f"除法运算: {result}")

6.2 导入指定的方法

语法如下:from module_name import function_0,function_1,function_2

定义模块函数

def sayHello(name):
    print(f"Hello, {name}")
def saygoodbye(name):
    print(f"Goodbye, {name}")

导入指定方法及调用

from cal01 import sayHello,saygoodbye
sayHello('jay zhou')
saygoodbye('marilyn manson')

6.3 使用as给函数指定别名

如果要导入的函数的名称太长或者可能与程序中既有的名称冲突,可以指定简短且唯一的别名:函数的另一个名称。如果给函数指定这种特殊的别名,需要在导入的时候做。

如上面的函数

from cal01 import sayHello as hello,saygoodbye as bye
hello('jay zhou')
bye('marilyn manson')

6.4 使用as给模块指定别名

使用方法同上

import cal01 as cal
cal.sayHello('zhangsan')
cal.saygoodbye('lisi')

6.5 导入模块中的所有函数

使用星号(*)可以导入模块中的所有函数。实际开发中最好不要使用这方式,因为如果模块中有函数的名称与当前项目中既有的名称相同,可能导致意外的效果。最好的做法:那么只导入需要使用的函数,要么导入整个模块并使用点号调用。

6.6 函数编写规范

在编写函数时,需要记住一些细节。应给函数指定描述性名称,且只适用小写字母和下划线。每个函数都应包含简要阐述其功能的注释。

在给形参指定默认值时,等号两边不要有空格:

def function_name(parameter_0,parameter_1='default value')

函数调用中的关键字实参也应遵守这个约定

function_name(value_0,parameter_1='value')

更多推荐