函数能提高应用的模块性,和代码的重复利用率。Python提供了许多内建函数,比如print()。但我们可以根据需求创建函数,即用户自定义函数。
一、定义函数的规则
- 以def a关键词开头,后接函数标识符名称和圆括号()
- 任何传入参数和自变量必须放在圆括号内,圆括号内可以用于定义参数。
- 函数第一行可以选择性使用字符串用于放函数功能说明。 函数内用以冒号:起始,且缩进。
- return[表达式]技术函数,选择性地返回一个值给调用方。不带return返回None
1 基本语法
(1)函数调用
def functionname( parameters ):"函数_文档字符串"function_suitereturn [expression]
示例:
#定义函数
def red(name):"打印传入的字符串到标准显示设备上"print("hello,",name)return(name)
#调用函数
red("大山很山")
运行结果:
hello, 大山很山
(2)函数返回 return语句
return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。
def sum(arg1, arg2):# 返回2个参数的和."total = arg1 * arg2return total# 调用sum函数
total = sum(2, 30)
print("函数 : ", total)
结果如下:
函数 : 60
二、参数说明
Python函数可以有任意数量的参数,也可以没有参数。它们还可以返回值。
示例如下:
# 定义一个函数,计算两个数的和
def add_numbers(a, b):return a * b# 调用函数并存储返回值
result = add_numbers(3, 5)
# 打印结果
print(result) # 输出:15
1、重要概念:可变对象和不可变对象
在Python中,对象根据其是否可以改变其内容被分为不可变对象(immutable objects)和可变对象(mutable objects)。这两种类型的对象在处理上有一些重要的区别,特别是在赋值、函数参数传递以及作为字典的键等方面。
类型属于对象,变量是没有类型的。
#举例说明
a = [1,2,3]
a = "hello"其中[1,2,3]是list类型,"hello"是String类型。变量a 是没有类型的,它仅是一个对象的引用(一个指针),可以指向list类型,也可指向string类型
(1)不可变对象
不可变对象在创建后其内容就不能被改变。常见的不可变对象类型包括:
- 整型(int)
- 浮点型(float)
- 复数(complex)
- 字符串(string)
- 元组(tuple)
- frozenset(冻结集合)
例如,字符串是一个典型的不可变对象。一旦你创建了一个字符串,你不能改变它内部的字符。如果你尝试改变它,Python实际上会创建一个新的字符串对象。
#示例1
s = "hello"
s[0] = 'H' # 这会引发TypeError,因为字符串是不可变的
#示例2:
def ChangeInt(a):a = 5print("函数内的值:",a) # 结果是 5b = 3
#调用自定义的函数
ChangeInt(b)
print("函数内的值:",b) # 结果是 3
运行结果:
函数内的值: 5
函数内的值: 3
(2)可变对象
可变对象在创建后其内容可以被改变。常见的可变对象类型包括:
- 列表(list)
- 字典(dict)
- 集合(set)
列表是一个典型的可变对象。你可以添加、删除或修改列表中的元素。
#示例1:
lst = [1, 2, 3]
lst[0] = 0 # 可以修改列表中的元素
lst.append(4) # 可以添加新的元素
print(lst) #输出[0, 2, 3, 4]
#示例2:
def changeme(mylist):"修改传入的列表"mylist.append([1, 2, 3, 4])print("函数内的值: ", mylist)return# 调用changeme函数
mylist = [1, 1, 1]
changeme(mylist)
print("函数外的值: ", mylist)
运行结果如下:
函数内的值: [1, 1, 1, [1, 2, 3, 4]]
函数外的值: [1, 1, 1, [1, 2, 3, 4]]
(2)注意事项
①作为字典的键:不可变对象可以用作字典的键,因为它们的内容不会改变,可以确保键的唯一性。而可变对象不能用作字典的键,因为它们的内容可能会变,这会导致字典的行为变得不确定。
②函数参数传递:当不可变对象作为函数参数传递时,实际上传递的是对象的引用。但由于对象是不可变的,所以在函数内部对参数的任何修改都不会影响原始对象。相反,对于可变对象,函数内部对参数的修改会影响到原始对象。
③赋值操作:对不可变对象进行赋值操作实际上是创建了一个新的对象,并更新了变量引用。对可变对象进行赋值操作则只是改变了引用的对象,而不是对象本身的内容。
理解不可变对象和可变对象之间的区别对于编写高效且可靠的Python代码非常重要。它们影响了Python的内存管理、参数传递和对象比较等多个方面。
2、参数类型
- 必备参数
- 关键字参数
- 默认参数
- 不定长参数
(1)必备参数:【顺序和个数都很重要】
必须以正确的顺序传入函数,调用的数量不需和声明时的一样。
#示例:
def ChangeInt(a):a = 5print("函数内的值:",a) # 结果是 5
b = 3
ChangeInt() #TypeError: ChangeInt() missing 1 required positional argument: 'a'
ChangeInt(b)#正确
(2)关键字参数【顺序不重要,个数重要】
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
以下实例在函数 functionprint() 调用时使用参数名:
def functionprint( st):"打印任何传入的字符串"print(st)return
#调用functionprint函数
functionprint(st = "hello,python")
运行结果:
hello,python
关键字参数顺序不重要:
def functionprint_two(name, age):"打印任何传入的字符串"print("Name: ", name)print("Age ", age)return# 调用functionprint_two函数
functionprint_two(age=18, name="大山很山")
运行结果:
Name: 大山很山
Age 18
(3)默认参数 【顺序不重要,个数也不重要】
调用函数时,默认参数的值如果没有传入,则被认为是默认值。
def functionprint_two(name="lucy", age=32):"打印任何传入的字符串"print("Name: ", name)print("Age ", age)return# 调用functionprint_two函数
functionprint_two(age=18, name="大山很山")
functionprint_two(name="lily")
functionprint_two()
运行结果如下:
Name: 大山很山
Age 18
Name: lily
Age 32
Name: lucy
Age 32
(4)不定长参数
有时需要定义一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。基本语法如下:
def functionname([formal_args,] *var_args_tuple ):"函数_文档字符串"function_suitereturn [expression]
加了星号(*)的变量名会存放所有未命名的变量参数。
def functionprint_x(arg1, *vartuple):"打印任何传入的参数"print("输出:",arg1)for var in vartuple:print(var)return# 调用printinfo 函数
functionprint_x(1)
functionprint_x(2, "大山很山","hello")
运行结果如下:
输出: 1
输出: 2
大山很山
hello
三、匿名函数
使用 lambda 来创建匿名函数
lambda的主体是一个表达式,而不是一个代码块,比def简单很多。但仅能在lambda表达式中封装有限的逻辑进去。它拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
语法如下:
lambda [arg1 [,arg2,.....argn]]:expression
# 使用lambda自定义函数
multiplication = lambda arg1, arg2: arg1 * arg2# 调用sum函数
print("相乘后的值为 : ", multiplication(15, 15))
运行结果:
相乘后的值为 : 225
四、变量作用域
一个程序的所有的变量并不是在哪个位置都可以访问的。访问权限决定于这个变量是在哪里赋值的。
total = 10 # 这是一个全局变量
# 可写函数说明
def sum(arg1, arg2):# 返回2个参数的和."total = arg1 + arg2 # total在这里是局部变量.print("函数内是局部变量total : ", total)return total# 调用sum函数
sum(15, 15)
total1=sum(15, 15)
print("函数外是全局变量total : ", total)
print("函数外是全局变量total1 : ", total1)
运行结果如下:
函数内是局部变量total : 30
函数内是局部变量total : 30
函数外是全局变量total : 10
函数外是全局变量total1 : 30