函数基本知识
函数基本定义
函数(function),指通过专门的代码组织,用来实现特定功能的代码段,具有相对独立性,可供其他代码重复使用。
优点:
代码非常简练。
提高代码编写效率和质量。
代码功能可以自由共享。
- 函数定义基本语法
def 函数名([参数]):
函数体
[return 返回值]
- 函数使用格式说明
标准自定义函数由def关键字、函数名、“([参数]):”、函数体、[return 返回值] 五部分组成。
1)def关键字
Python语言任何函数定义必须以关键字def开始,其后空一格紧跟函数名。
2)自定义函数名
(1)不能与现有的内置函数名发生冲突。
(2)名称本身要准确表达函数的功能,建议使用英文单词全称开头,单词之间可以用下划线隔开。
(3)带中括号的参数,意味着函数可以有参数,也可以没有参数。参数传递对象可以是简单数据;可以是元组、列表、字典;也可以是类对象。
(4)函数体为实现函数功能的相关代码段。
(5)return语句后面空一格,跟需要返回的值。带中括号,意味着函数可以有返回值,也可以没有。
自定义函数
不带参数函数
- 格式
def 函数名():
函数体
- 案例
def factor_on_parameter(): # 不带参数的求因数的自定义函数
i = 1
nums = 10
print('%d的因数是:'% nums)
while i <= nums: # 循环求10的因数
if nums % i == 0: # 能整除10的整数是10的因数
print('%d' % i)
i += 1
factor_on_parameter() # 调用自定义函数
t = type(factor_on_parameter) # 检查函数类型
print(t)
# 10的因数是:
# 1
# 2
# 5
# 10
# <class 'function'>
带参数函数
- 格式
def 函数名(参数):
函数体
- 案例
def find_factor(nums):
i = 1
str1 = ''
print('%d的因数是:'% nums)
while i <= nums:
if nums % i == 0:
str1 = str1 + '' + str(i)
i += 1
print(str1)
num2 = [10, 15, 18, 25]
i = 0
num_len = len(num2)
while i < num_len:
find_factor(num2[i]) # 循环调用find_factor(nums)
i += 1
# 10的因数是:
# 1 2 5 10
# 15的因数是:
# 1 3 5 15
# 18的因数是:
# 1 2 3 6 9 18
# 25的因数是:
# 1 5 25
带返回值函数
- 格式
def 函数名([参数]):
函数体
return 返回值
- 函数返回值
不带return语句的函数,其实默认都返回None值。
print(factor_on_parameter())
# 10的因数是:
# 1
# 2
# 5
# 10
# None
return 语句在函数中除了返回值外,还起中断函数执行作用。
def test_f():
return 1
print('OK')
print(test_f())
# 1
- 案例
def find_factor(nums):
i = 1
str1 = ''
while i <= nums:
if nums % i == 0:
str1 = str1 + ' ' + str(i)
i += 1
return str1
num2 = [10, 15, 18, 25]
i = 0
num_len = len(num2)
return_str = ''
while i < num_len:
return_str = find_factor(num2[i])
print('%d的因数是:%s' % (num2[i], return_str))
i += 1
# 10的因数是: 1 2 5 10
# 15的因数是: 1 3 5 15
# 18的因数是: 1 2 3 6 9 18
# 25的因数是: 1 5 25
自定义函数的完善
- 函数文档
自定义函数编写完成后,需要考虑使用的方便性,如编程时间过后,也能轻易地知道函数的功能及如何使用。
def find_factor(nums):
'''
find_factor是自定义函数
nums是传递一个正整数的参数
以字符串形式返回一个正整数的所有因数
'''
i = 1
str1 = ''
while i <= nums:
if nums % i == 0:
str1 = str1 + ' ' + str(i)
i += 1
return str1
help(find_factor)
# find_factor(nums)
# find_factor是自定义函数
# nums是传递一个正整数的参数
# 以字符串形式返回一个正整数的所有因数
- 健壮性考虑
如果把函数的参数看作传递值的入口,必须考虑所有传递的值是否符合要求。
在以上代码注释段下添加:
if type(nums) != int:
print('输入值类型出错,必须是整数!')
return
if nums <= 0:
print('输入值范围出错,必须是正整数!')
return
把函数放到模块中
自定义函数建立后,如果需要被其他代码文件调用(以.py为扩展名的文件);或者需要通过共享,让其他程序员使用,那么就需要把函数代码放到一个可以共享的地方。在Python语言中,它就是通过建立独立的函数模块(Module)文件(以.py为扩展名的文件),共享给其他代码文件调用的。
- 建立函数模块
(1)在Python语言编辑器中,新建立一个空白的代码文件,用于存放自定义函数代码。
(2)编写并调试完成自定义函数代码。
(3)把只属于自定义函数的代码复制带函数模块文件上,若有多个自定义函数,按照顺序复制保存即可。 - 调用函数模块
在Python语言的编辑器里,除了默认内置函数外,其他函数的调用,必须先通过 import 语句进行导入,才能使用。
(1)用 import 语句导入整个函数模块
导入格式:import 函数模块名
import test_function # 导入模块
print(test_function.find_factor(10)) # 调用自定义函数
import语句导入函数后,通过模块名中间连接点号与函数名连接方式调用函数。
(2)用import 语句导入指定函数
导入格式:from 模块名 import 函数名1 [,函数名2,…]
from test_function import find_factor
print(find_factor(10)) # 直接调用函数
(3)用import语句调用导入所有函数
格式: from模块名 import *
(4)模块名、函数名别名方式
as使用格式:模块名[函数名] as 别名
import test_function as t
t.find_factor(10)
参数的变化
- 位置参数
在传递参数值时,必须和函数定义的参数一一对应,位置不能打乱。
def test1(name, age): # 带两个固定参数
print('姓名%s,年龄%s' % (name, str(age)))
test1('ajian', 18)
# 姓名ajian,年龄18 # 正确结果
test1(18, 'ajian')
# 姓名18,年龄ajian # 错误结果
- 关键字参数
为了避免传递值出错,利用“参数名=值”,在调用函数时显示表示,而且无需考虑参数的位置顺序。
test1(name='atian', age=20)
test1(age=20, name='atian')
test1('atian', age=20)
# 执行结果都为
# 姓名aian,年龄20
test1(name='atian', 20) # 该指定错误,不支持左边指定,右边不指定
- 默认值
为参数预先指定默认值,当没有给该参数传值时,该参数自动选择默认值。
def test1(name='', age=20): # name默认值为'',age默认值为20
print('姓名%s,年龄%s' % (name, str(age)))
test1(18)
test1()
test1('atian', 18)
# 姓名18,年龄20 # 函数默认输入一个值的情况下,把值赋给了第一个参数
# 姓名,年龄20
# 姓名atian,年龄18
- 不定长参数*、**
1)传递任意数量的参数值
格式:函数名([param1, param2,…,] *paramX)
带 “ * ” 的paramX参数,可以接收任意数量的值。但一个自定义函数只能有一个带 “ * ” 的参数。而且只能放置最右边的参数中,否则自定义函数执行时报语法出错。
def watermelon(name, *attributes):
print(name)
print(type(attributes))
description = ' '
for get_t in attributes:
description += ' ' + get_t
print(description)
watermelon('西瓜', '甜', '圆形', '绿色') # 调用自定义函数,任意传3个参数
print('-----------------------------------------------')
watermelon('西瓜', '甜', '圆形', '绿色', '红瓤', '无籽') # 任意传5个参数
# 西瓜
# <class 'tuple'>
# 甜 圆形 绿色
# -----------------------------------------------
# 西瓜
# <class 'tuple'>
# 甜 圆形 绿色 红瓤 无籽
2)传递任意数量的键值对
格式:函数名([param1, param2,…,] **paramX)
带“ ** ”paramX参数用法与带 “ * ” 用法类似,区别:传递的时键值对。
def watermelon(name, **attributes):
print(name)
print(type(attributes))
return attributes
print(watermelon('西瓜', taste='甜', shape='圆形', color='绿色'))
# 西瓜
# <class 'dict'>
# {'taste': '甜', 'shape': '圆形', 'color': '绿色'}
传递元组、列表、字典值
- 传递元组
def watermelon(name, attributes):
print(name)
print(type(attributes))
return attributes
get_t = watermelon('西瓜', ('甜', '圆形', '绿色'))
print(get_t)
# 西瓜
# <class 'tuple'>
# ('甜', '圆形', '绿色')
- 传递列表
get_L = watermelon('西瓜', ['甜', '圆形', '绿色'])
print(get_L)
# 西瓜
# <class 'list'>
# ['甜', '圆形', '绿色']
- 传递字典对象
attr = {'taste': '甜', 'shape': '圆形', 'color': '绿色'}
get_D = watermelon('西瓜', attr)
print(attr)
# 西瓜
# <class 'dict'>
# {'taste': '甜', 'shape': '圆形', 'color': '绿色'}
- 出现的问题
在自定义函数内获取从参数传递过来的列表、字典对象后,若在函数内部对它们的元素进行修改,则会同步影响函数外部传递前的变量的元素。
解决方案:
利用列表copy()方法实现原对象的复制。 - 传递对象总结
根据传递对象在函数里的变化情况,可以把传递的对象分为不可变对象、可变对象。数字、字符串、元组属于不可变对象;列表、字典属于可变对象。
不可变对象在函数里进行值修改时,会变成新的对象(在内存产生新的地址)。
可变对象在函数里进行值修改时,函数内外还是一个对象,但是值同步发送变化。