函数
1. 概念
python的内置函数:
print() 在控制台输出
input() 获取控制台输⼊的内容
type() 获取变量的数据类型
len() 获取容器的⻓度 (元素的个数)
range() ⽣成⼀个序列[0, n).....
函数: 可以把多行代码(实现一个特定功能)放在一起, 并且给它起一个名字, 在需要使用多行代码的时候, 可以使用名字代替.(函数必须先定义后调用)
定义函数的好处: 减少代码的冗余, 提高编程效率
2. 定义和调用
定义
-
函数的定义就是给多行代码起名字的过程
-
函数的定义需要使用关键字: def, 单词 define
def 函数名():
函数中的代码
函数中的代码
在 def 缩进的代码, 都属于这个函数
函数名要满足标识符规则, 见名知意
def 这行代码的最后一个需要 冒号
函数定义不会执行函数中的代码, 想要执行, 必须调用
调用
-
函数调用, 就是使用多行代码的过程
-
语法: 函数名()
代码: 写一个打招呼的函数,并且进行调用
python
# 函数的定义
def say_hello():
print("hello1")
print("hello2")
print("hello3")
print("hello4")
# 函数的调用
say_hello()
say_hello()
say_hello()
say_hello()
3. 函数的文档注释
总而言之, 就是一个在函数 def 下方,用三对双引号来书写的注释, 对函数的作用和使用方法进行说明, 比如: 有哪些参数, 返回值是什么

常用快捷键
4.1 在函数名上,使⽤快捷键 Ctrl q 查看
4.2 在函数名上,使⽤ 快捷键 Ctrl B 跳转到函数定义的地⽅查看
4.3 在函数名上, 按住 Ctrl 键,点击函数名,跳转到函数定义的地⽅查看
4. 函数的参数
-
形式参数: 函数定义的()里面写入的变量称之为函数的参数
-
实际参数: 函数在调用的时候, 传入的参数
-
函数在调用的时候, 会把函数的实际参数值传递给形参
-
好处: 让函数更加通用, 函数中的数据值不是固定的, 是调用的时候, 使用者传递的(使用的时候实际参数的个数和形式参数的个数要一致)
-
使用场景: 判断 函数中 数据值是不是固定不变的, 如果是变化的, 就可以使用参数传参
代码:
python
def sun_2_num(a, b): # a, b 形参
c = a + b
print(c)
sun_2_num(10, 20) # 10, 20 实参 10 给 a, 20 给 b
sun_2_num(1, 2)
sun_2_num(20, 39)
5. 函数的嵌套调用
在一个函数里面调用另外一个函数
-
代码从上到下执⾏的
-
函数定义不会执⾏函数中的代码
-
函数调⽤会进⼊函数中执⾏函数中的代码
-
函数中的代码执⾏结束,会回到调⽤的地⽅继续向下执⾏
代码
python
# 1. 定义名为test01的函数,打印当前函数的名称
def test01():
print(1)
print('func01')
print(2)
# 2. 定义名为test02的函数,打印当前函数的名称,并 调⽤test01函数
def test02():
print(3)
print('func2')
test01()
print(4)
print(5)
test02()
print(6)
6. 函数的返回值
返回值: 函数执行的结果
len(): 返回容器的长度
input() 返回键盘输入的内容
-
想要函数中返回一个数据, 需要使用 return 关键字
-
为什么使用返回值? 在函数中可能通过各种代码,得到的数据结果,想要在函数外部使⽤,就需要使⽤返回值(函数的值要被另一个函数使用)
-
return 的作用:1> 把一个数据值返回到调用的地方. 2> 函数遇到 return 会结束函数的执行
-
return 只能在函数中使用, 函数如果没有写return 默认返回的是 None
代码:
定义名为 input_username 的函数, 获取⽤户输⼊的⽤户名
定义名为 input_password 的函数, 获取⽤户输⼊的密码
定义名为 login 的函数, 判断获取的⽤户名和密码信息
要求当获取的⽤户名为:admin 并且密码为: 123456 时, 输出"登录成功!",否则提示"⽤户名或 密码错误!"
python
# 1. 定义名为 input_username 的函数, 获取⽤户输⼊的⽤户名
def input_username():
return input("请输入用户的名称: ")
# 2. 定义名为 input_password 的函数, 获取⽤户输⼊的密码
def input_password():
return input("请输入用户的密码: ")
# 3. 定义名为 login 的函数, 判断获取的⽤户名和密码信息
# 4. 要求当获取的⽤户名为:admin 并且密码为: 123456 时, 输出"登录成功!",否则提示"⽤户名或 密码错误!"
def login():
username = input_username()
password = input_password()
if username == "admin" and password == "123456":
print("登录成功")
else:
print("用户名或者密码错误!")
login()
模块和包
1. 模块导入的方法
模块的概念
-
在python中, 每个代码为文件都可以称为一个模块
-
在模块中, 别人书写好的功能(变量, 函数,类), 我们可以拿来直接使用
-
文件名(模块名)命名符合标识符规则
-
想要使用别人模块中写好的功能, 就需要先导入别人写好的功能
-
可以使用 as 关键字给模块/功能起别名
导入模块的方法
方法一: 多用于导入系统中的常用模块和功能
import 模块名 # 模块名 就是代码文件名, 不要.py
使用其中的功能
模块名.功能名 # 功能可以是变量. 函数 和类
代码:
python
import random
num = random.randint(1, 10)
print(num)
方式二: 多用于导入自己写的代码, 或者第三方的模块, 可以使用快捷键 Alt 进行回车
from 模块名 import 功能名 # 导入指定的功能
使用
功能名

代码
python
from random import randint
num = randint(1, 10)
print(num)
__name__变量
-
导入模块的时候, 会执行模块中的代码
-
作用: 如果在导入模块的时候, 模块中的部分代码不想被执行, 可以使用__name__来执行
-
__name__变量, 是 Python 的内置变量, 每个代码文件中, 都有这个变量
在模块中 name 打印的值是'main'

在被导入的模块中, __name__变量的值, 是模块的文件名

因此我们不想模块的一部分代码,影响了被导入模块的代码就可以使用这个操作
python
if __name__ =='__main__':
print("hello")
快捷键: 写完 main 后直接回车

2. 模块导入的顺序
-
在导入模块的时候, 会从代码所在的目录进行导入
-
如果没有找到, 会去 Python 系统目录进行导入
-
如果还没有找到就报错
注意: 自己定义的代码文件名不要和导入的系统模块文件名一样
3. 包的创建
包: 把多个模块放在一个目录集中进行管理, 并在这个目录中创建一个__init__.py 文件, 就是一个包
创建包:

4. 包的导入
方式一:
import 包名.模块名
使用
包名.模块名.工具名
模块名: xxx.py. 工具名: 里面的函数名
方式二:
from 包名 import 模块名
使用
模块名.工具名
方式三: 使用快捷键导包
from 包名.模块名 import 工具名
直接使用工具名
工具名
例子:
需求:
模拟开发人员实现登录功能,定义一个函数能够接收用户输入的用户名、密码、验证码,根据不同的测试数据返回不同的验证结果
已知正确的登录信息(用户名:admin、密码:123456、验证码:8888)
要求1:创建login_service.py模块开发登录功能代码,并存放到service包中
要求2:创建test_login.py模块开发测试代码,并存放到script包中
要求3:至少测试3种测试场景
代码:
python
from service.login_service import input_username, input_password, input_code
def test_login():
if input_code() == "8888":
if input_username() == "admin" and input_password() == "123456":
print("登录成功!")
else:
print("账号或者密码错误")
else:
print("验证码错误")
if __name__ == '__main__':
test_login()
login_service.py
python
def input_username():
return input("请输入用户名: ")
def input_password():
return input("请输入密码: ")
def input_code():
return input("请输入验证码: ")
变量的进阶
1. 变量的引用
-
定义变量的时候, 变量和数据都会在内存开辟空间
-
变量所对应的内存空间存储的是 数据所在内存的地址
-
变量中保存数据的地址, 就称为引用
-
Python 中所有数据的传递, 传递的都是引用(地址)
-
赋值运算符(=), 会改变变量的引用, 只有 = 可以修改变量的引用
-
可以使用 id(变量) 函数, 查看变量的引用
代码
python
a = 1
# b指向的是值1所在的地址
b = a
print(id(a), id(b))
print("=====")
a = 2
# a的引用修改了
print(id(a), id(b))
print("=====")
mylist = [1, 2, 3]
print("mylist的地址", id(mylist))
print("第一个元素的地址", id(mylist[0]))
# 修改其中一个的地址
mylist[0] = 13
print("mylist的地址", id(mylist))
print("修改后第一个元素的地址", id(mylist[0]))
# 修改mylist
mylist = [1, 2, 3]
print("mylist的地址", id(mylist))
2. 可变类型与不可变类型
根据内存中的数据据是否允许修改, 把数据类型分为: 可变类型, 不可变类型
简单理解: 不使用等号, 能不能使用其他方式修改数据值
可变类型: 可以修改
列表(list): lisr.append()
字典(dict): dict.pop()
集合(set): set.pop()
不可变类型: 不允许修改
数字类型(int,float,bool)
字符串(str)
元组(tuple)
代码:
python
my_tuple = (1, 2, [10, 20]) # 元组中 存储的 1 的地址, 2 的地址, 列表的地址
print(my_tuple, id(my_tuple), id(my_tuple[-1]), id(my_tuple[-1][-1]))
my_tuple[-1][-1] = 30 # 修改的列表中最后一个位置的引用
print(my_tuple, id(my_tuple), id(my_tuple[-1]), id(my_tuple[-1][-1]))
3. 局部变量和全局变量
根据变量定义的位置, 把变量分为: 局部变量和全局变量
局部变量
-
在函数内部定义的变量, 称为局部变量
-
特点
局部变量只能在当前函数内部使用
可以在不同函数内定义名字相同的局部变量
- 生命周期(使用范围)
在函数执行(调用)的时候被创建
在函数执行结束被销毁的时候被删除
-
形参可以认为是局部变量
-
如果想要在函数外部使用局部变量的值, 使用 return 返回
代码
python
def func1():
num = 10 # 局部变量
print(num)
def func2():
num = 20
print(num)
if __name__ == '__main__':
func1() # 10
func2() # 20
func1() # 10
全局变量
-
在函数外部定义的变量
-
特点
全局变量: 可以在任意函数内访问(读取)
想要在函数内部修改全局变量的引用, 需要使用 global 关键字声明(使用 global 关键字可以声明为全局变量)
如果在函数内部出现和全局变量名字相同的局部变量, 在函数内部使用的是局部变量(局部优先)
- 生命周期
代码执行的时候创建, 执行结束销毁
代码:
普通变量
python
# 定义全局变量
g_num = 10
def func_1():
print(g_num) # 使用全局变量
def func_2():
g_num = 20 # 定义局部变量
print(g_num)
def func_3():
global g_num # 声明为全局变量
g_num = 30
print(g_num)
if __name__ == '__main__':
print(g_num) # 10
func_1() # 10
func_2() # 20
func_1() # 10
print(g_num) # 10
func_3() # 30 修改了全局变量, 将全局变量的值改为30 了
func_1() # 30
g_num = 100
func_1() # 100 修改全局变量的值
func_2() # 20 局部变量
func_3() # 30
func_1() # 30
容器
python
def func1():
list1.append(10)
def func2():
list1 = [1, 1] # 定义局部变量, 不影响全局变量
list1.append(0)
def func3():
global list1 # 全局变量
list1.pop() # 删除最后一个数据
def func_5():
list1.pop() # 用的全局变量,没有改引用
def func4():
global list1 # 全局变量
list1 = [1]
if __name__ == '__main__':
list1 = [1, 2]
func1()
print(list1) # ①[1, 2] ②[1, 2, 10](√) ③报错
func2()
print(list1) # ① [1, 1, 0] ②[1, 2, 10](√) ③报错
func3()
print(list1) # [1, 2]
# func_5()
# print(list1) # ②[1, 2] ①[1]对
func4()
print(list1) # [1]
函数进阶
1. 函数返回多个数据值
return 在python里面可以有多个返回值
-
返回数据值
-
结束函数的运行
函数中如果想要返回多个数据值, 一般是组成元组进行返回
代码
python
def calc(a, b):
'''
返回俩个数的和以及差
:param a:
:param b:
:return:
'''
return a + b, a - b
rs = calc(10, 20)
print(rs)
2. 函数传参的方式
指如何把实参的值传递给形参
-
位置传参: 在函数调用的时候按照 形参的顺序把实参的值传递给形参
-
关键字传参: 在函数调用的时候, 指定将实参传递给哪个形参
-
混合使用: 位置参数必须放在关键字参数的前面
代码:
python
def show_info(name, age):
print(f"name:{name}, age: {age}")
# 位置传参
show_info('小明', 18)
# 关键字传参
show_info(age=18, name='张三')
# 混合使用
show_info('李四', age=17)
3. 缺省参数(默认参数)
-
定义: 在函数定义的时候, 给形参一个默认的数据值, 这个参数就是缺省参数((默认参数)
-
特点: 在函数调用的时候, 缺省参数可以不用传递实参值
如果不传递实参值, 使用的就是默认值
如果传递实参值, 使用的就是传递的实参值
- 注意点: 缺省参数必须写在 普通参数的后边
代码
python
"""
定义 show_info 参数 姓名,年龄, 性别, 将年龄设置为默认参数 18, 性别设置为默认 保密
"""
def show_info(name, age=18, sex='保密'):
print(name, age, sex)
# 调用
show_info('张三', 19)
4. 多值参数(可变参数/不定长参数)
-
在函数定义的时候, 不确定实参有多少个, 此时就可以使用多值参数
-
在普通参数前面加上个 * , 这个参数就变成了 多值参数
-
这个参数可以接受任意多个位置的数据, 类型 元组
-
这个形参一般写作 args(arguments), 也就是 *args
注意: argument: 实参 parameter: 形参
参数顺序: 普通参数, 缺省参数, 多值参数
代码: 定义一个函数,my_sum,作用,可以对任意多个数字进行求和计算
python
def my_sum(*args):
sum = 0
for i in args:
sum += i
return sum
print(my_sum(11, 2, 77, 4))
# 需求对元组中的所有数据使用my_sum进行求和
my_tuple = (1, 2, 3, 4, 5)
# 想要把列表(元组) 中的数据作为位置参数进行传递, 只需要在列表(元组)前边加上一个 * ,进行拆包即可
print(my_sum(*my_tuple)) # 15
5. 匿名函数
- 语法: lambda 参数1, 参数2: 一行代码 # 只能实现简单的功能, 只能写一行代码, 匿名函数一般不直接调用, 作为函数的参数使用
2)代码:
python
# 1, 定义匿名函数, 参数为两个整数数字, 求两个数字的乘积
lambda a, b: a * b
# 2, 定义匿名函数, 参数为一个字典, 返回字典中 键为 age 的值
lambda x: x.get('age')
lambda x: x['age']
user_list = [
{'name': '张三', 'age': 22, 'title': '测试工程师'},
{'name': '李四', 'age': 24, 'title': '开发工程师'},
{'name': '王五', 'age': 21, 'title': '测试工程师'}
] #
user_list.sort() # 只能对数字,字符串排序
# TODO 根据字典的 age 键 排序
# key是一个可选参数,用于指定一个函数,这个函数会作用在每个元素上,然后根据这个函数的返回值进行排序。
# 想要对列表中的字典排序,需要 key 形参来指定根据字典中的什么键排序
# key 这个参数需要传递一个函数,使用匿名函数
# 列表.sort(key=lambda x: x['键'])
# 普通函数: def func(x):
# return x['age']
user_list.sort(key=lambda x: x.get('age'))
print(user_list)
# lambda函数
user_list.sort(key=lambda x: x['age'])
# user_list.sort(key=func)
print(user_list)
案例

代码
python
# 全局变量
all_student = []
def make_student():
'''
录入学生信息
:return:
'''
name = input("请输入姓名:")
age = input("请输入年龄:")
student_dic = {
'name': name,
'age': age
}
return student_dic
def show_info():
'''
展示学生信息
:return:
'''
print("-------学生列表信息-------")
j = 1 # 初始序号
for stu_dict in all_student: # stu_dict 字典
print(f"{j}\t\t{stu_dict.get('name')}\t\t{stu_dict.get('age')}")
j += 1
print("-------------------------")
def get_count():
'''
获取学生总数
:return:
'''
return len(all_student)
def search_stu():
'''查询学生信息'''
name = input("请输入查询的学生名字:")
for student_list in all_student:
if student_list.get('name') == name:
print(f"姓名: {name}, 年龄:{student_list.get('age')}")
return
print(f"对不起,名字叫{name}的学生不存在")
if __name__ == '__main__':
all_student.append(make_student())
all_student.append(make_student())
print(all_student)
show_info()
print(get_count())
search_stu()