Python3 函数
函数是 组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
定义一个函数
规则:
- 函数代码块以 def 关键词开头 ,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串---用于存放函数说明。
- 函数内容以冒号 : 起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。
语法:
Python 定义函数使用 def 关键字,一般格式如下:
def 函数名(参数列表):
函数体

为什么要有函数:将需要重复使用的某个功能,整合成一个函数,这样每次使用的时候就只需要调用该函数,而不是重写一段实现该功能的代码
eg:
def max (a,b):
#定义一个函数,输入两个参数,返回较大值。
if a>b:
return a;
else:
return b;
#如果我想比较3和4,5和6的大小,就可以调用两次这样的函数,而不是重复写两次比较大小的代码
print(max(3,4));
print(max(5,6));
运行结果:

这里的max就是我所定义的函数标识符(也就是函数名),圆括号里面的就是我的函数参数,如果要调用我的这个函数,就可以给我这个函数传入两个参数,比如下面的3和4,5和6。print(max(3,4))的这个过程就是函数调用。
参数传递
在 python 中,类型属于对象,对象有不同类型的区分 ,变量是没有类型的:
对象:
在编程中,对象是一个包含数据和功能的实体 。它可以被认为是一个具体的实例,具有特定的属性(数据)和方法(功能)。在Python中,几乎所有的东西都是对象,包括数字、字符串、列表、字典等。
特点:
数据和行为:对象不仅存储数据(如数值、文本等),还可以执行操作(方法)。
类型:每个对象都有一个类型,决定了它可以执行哪些操作。 例如,一个字符串对象可以使用字符串方法(如 .upper() ,将小括号内的字符串从小写变成大写),而一个列表对象可以使用列表方法(如 .append(),作用是在列表的最后添加上小括号内的元素)。
eg:
# 创建一个字符串对象
s = "Hello, World!" # s 是一个字符串对象
print(s.upper()) # 使用字符串对象的方法,这里是将字符串转换成大写字母,输出: "HELLO, WORLD!"
运行结果:

变量:
变量是一个用于存储数据的命名空间 。可以把它看作是一个标签,指向某个对象 。变量本身并不包含数据,而是指向存储在内存中的数据对象。你可以通过变量来访问和操作这些对象。
动态性:在Python中,变量可以指向任何类型的对象,并且可以在运行时改变指向的对象。例如,你可以将一个整数赋值给变量,然后再将一个字符串赋值给同一个变量。
命名:变量有一个名称,程序员可以使用这个名称来引用存储在其中的对象。eg:
eg:
# 创建一个变量并赋值
x = 10 # x 是一个变量,指向整数对象 10
print(x) # 输出: 10
x = "Hello" # 现在 x 指向一个字符串对象 "Hello"
print(x) # 输出: Hello
运行结果:

对象 是包含数据和功能的实体 ,具有特定的类型和方法。
变量 是指向对象的命名标签,可以动态改变指向不同的对象。
可更改(mutable)与不可更改(immutable)对象
在 python 中,strings, tuples, 和 numbers 是不可更改的 对象,而list,dict 等则是可以修改的对象。
-
不可变类型: 变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变 a 的值,相当于新生成了 a。
-
可变类型: 变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
-
不可变类型: 类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。
-
可变类型: 类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响。
python 中一切都是对象 ,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
eg:
def change (a):
# 改变a的值,使其减一。
a -= 1;
return a;
# 调用函数
a1=10;
print("change(a1):",change(a1));#输出: 9
print("a:",a1);#输出: 10,a1的值没有改变,因为函数只是返回了一个新的值,并没有修改原来的变量。
def change1(a_list):
# 改变a_list中第一个元素的值,使其减一。
a_list[0] -= 1;
return a_list;
def change2(a_list):
#对a_list进行重赋值;
a_list = [1,2,3];
return a_list;
# 调用函数
a2=[10,20,30];
print("change1(a2):",change1(a2));#输出: [9, 20, 30]
print("a2:",a2);#输出: [9, 20, 30],a2的值已经改变,因为函数直接修改了原来的列表。
print("change2(a2):",change2(a2));#输出: [1, 2, 3]
print("a2:",a2);#输出: [9,20,30],a2的值并未改变
运行结果:

从结果来看,这些变量似乎都是一个类似指针的存在,上面的a1存储的是10的地址空间,然后传到change()函数中的a,这个是函数中的参数a(新创建的)也指向了10的地址空间,然后修改参数a,相当于让它指向了9所在的地址空间;下面的a2也是同理,a2指向的是列表的地址空间,然后传到change1(),change2()函数中的参数a_list中,a_list也指向这个列表的地址空间,然后如果修改列表内部元素的值,就根据这个列表的地址空间找到其内部元素的所在,进行修改,而该列表地址并没有改变,改变的是其内部元素的地址,而当我直接对列表重赋值的话,相当于让a_list指向了一个全新的列表,这个时候a_list指向的列表就变了,所以和a2就没有关系了,所以后面a2的值并没有改变。
参数
以下是调用函数时可使用的正式参数类型:
- 必需参数
- 关键字参数
- 默认参数
- 不定长参数
必需参数
必需参数须以正确的顺序 传入函数。调用时的数量必须和声明时的一样。
eg:
def max (a,b):
#定义一个函数,输入两个参数,返回较大值。
if a>b:
return a;
else:
return b;
a=1;
b=12;
print(max(a,b));#一定要传两个参数,否则会报错。
print(max());#如果不传参数,则会报错。
运行结果:

错误的意思是少了两个所必须的参数。
关键字参数
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
关键字参数就是你要传入到函数里面的那个变量的名字和函数所定义的那个参数的名字是一样的。
但关键字参数在调用函数时要以"参数名=值"的形式传递参数才行。
eg:
def print1(a,b):
#打印参数b的值。
print(b);
a=10;
b=20;
print1(b,a);#这个还是按顺序传参的
print1(b=12,a=13);#这个是根据关键字传参的
运行结果:
