视频链接:https://www.bilibili.com/video/BV1o4411M71o?p=15&share_source=copy_web
课件PDF–链接: https://pan.baidu.com/s/1kYX3FcDasnFMLT8FCuHIGw 提取码: 86hy
以下均为个人笔记

一、函数

1.1 函数的使用步骤

定义函数
调⽤函数
注意:

  1. 不同的需求,参数可有可⽆。
  2. 在Python中,函数必须先定义后使⽤。
# 因为函数要先定义再调用,所以步骤2和3 要在步骤1 的前面书写
# 2.确定选择功能界面:显示余额 存款 取款; # 3.封装函数

def sel_func():
    print('显示余额')
    print('存款')
    print('取款')

# 1.搭建整体框架
"""
输入密码登录后显示功能; 查询余额后显示功能; 取款后显示功能
"""
print('恭喜您登登录成功')
# 显示功能界面 -- 在需要的位置调用函数
sel_func()

print('您的余额是1000000')
# 显示功能界面 -- 在需要的位置调用函数
sel_func()

print('您取走了1000元钱')
# 显示功能界面 -- 在需要的位置调用函数
sel_func()
# 1.使用一个函数 2.测试注意事项
# 需求:一个函数:打印 hello world

# info_print()  # 报错

# 定义函数
def info_print():
    print('hello world')

# 调用函数
info_print()# hello world

"""
结论:
1.函数先定义后调用,如果先调用会报错
2.如果没有调用函数,则函数里面代码不会执行
3.函数执行流程***
    当调用函数的时候,解释器回到定义函数的地方去执行下方缩进的代码,当这些代码执行完,回到调用函数的地方继续向下执行
    定义函数的时候,函数体内部缩进的代码并没有执行
"""

1.2 函数的参数作用

# 1.函数:固定数据1 和 2 加法
def add_num1():
    result = 1 + 2
    print(result)

add_num1()#3

# 2.参数形式传入真实数据 做加法运算
def add_num2(a,b):   # a 和 b是形参
    result = a + b
    print(result)

add_num2(10,20)   #  10 和 20 是实参
add_num2(2,3)#5

# add_num2(2)  #报错  因为定义函数是两个参数,所以传入数据也要是两个

1.3 函数的返回值作用

# 定义一个函数返 返回 烟
def buy():
    return '烟'

goods = buy()
print(goods)#烟

"""
return 作用:
1.负责函数返回值
2.退出当前函数,导致return下方所有代码(函数体内部)不执行
"""
# 需求: 制作计算器:计算任意两个数字的加法结果,并返回结果
"""
1.定义函数;2个参数 和 return返回值
2.调用函数,传入两个真实数据--这里既有返回值结果,打印这个结果即可
"""

def sum_num(a,b):
    return a + b

result = sum_num(1,2)
print(result)#3

1.4 函数的说明文档

答:注释
思考:如果代码多,我们是不是需要在很多代码中找到这个函数定义的位置才能看到注释?如果想更⽅
便的查看函数的作⽤怎么办?
答:函数的说明⽂档(函数的说明⽂档也叫函数的⽂档说明。)
语法:

def 函数名(参数):
 	""" 说明⽂档的位置 """
 	代码
 ......

#查看函数的说明文档
help(函数名)
#  help(len)  # help 函数作用:查看函数的说明文档(函数的解释说明信息)

def sum_num(a,b):
    """求和函数"""
    return a + b

help(sum_num)

def sum_num1(a,b):
    """
    求和函数
    :param a: 参数一
    :param b: 参数二
    :return: 返回值
    """
    return a + b
help(sum_num1)

黑马python讲义PDF 黑马python课件_数据

1.5 函数嵌套调用

所谓函数嵌套调⽤指的是⼀个函数⾥⾯⼜调⽤了另外⼀个函数

# 两个函数 testA 和testB -- 在A里面嵌套B
# B 函数
def testB():
    print('B函数开始----')
    print('这是B函数----')
    print('B函数结束----')

# A 函数
def testA():
    print('A函数开始----')
    # 嵌套调用B
    testB()
    print('A函数结束----')
testA()
"""
A函数开始----
B函数开始----
这是B函数----
B函数结束----
A函数结束----
"""

1.6 函数应用

1.打印一条横线

# 1.打印一条横线
def print_line():
    print('-' * 20)

#print_line()

# 2.函数嵌套调用 实现多条横线
def print_lines(num):
    i = 0
    while i < num:
        print_line()
        i += 1

print_lines(5)

求三个数之和

def sum_num(a,b,c):
    return a + b + c
result = sum_num(1,2,3)
# print(result)

# 求三个数的平均值

def average_num(a,b,c):
    # 先求和,再除以3
    sumResult = sum_num(a,b,c)
    return sumResult / 3

averageResult = average_num(2,3,4)
print(averageResult)

二、函数进阶

2.1 变量作用域

变量作⽤域指的是变量⽣效的范围,主要分为两类:局部变量和全局变量。

  • 局部变量
    所谓局部变量是定义在函数体内部的变量,即只在函数体内部⽣效。
def testA ():
    a = 100
    print(a)  # 函数体内部访问,能访问到a变量

testA()#100
# print(a) # 报错: a变量是函数体内部的变量,函数外部无法访问-- a是一个局部变量

局部变量的作⽤:在函数体内部,临时保存数据,即当函数调⽤完成后,则销毁局部变量。

  • 全局变量
    所谓全局变量,指的是在函数体内、外都能⽣效的变量。
    思考:如果有⼀个数据,在函数A和函数B中都要使⽤,该怎么办?
    答:将这个数据存储在⼀个全局变量⾥⾯
# 声明全局变量:函数体内外都能访问到
a = 100
print(a)#100

def testA():
    print(a)
def testB():
    print(a)
    
testB()#100
testA()#100

思考: testB 函数需求修改变量a的值为200,如何修改程序?

a = 100
def testA():
	 print(a)
def testB():
	 a = 200
	 print(a)
testA() # 100
testB() # 200
print(f'全局变量a = {a}') # 全局变量a = 100

思考:在 testB 函数内部的 a = 200 中的变量a是在修改全局变量 a 吗?
答:不是。观察上述代码发现,15⾏得到a的数据是100,仍然是定义全局变量a时候的值,⽽没有返回testB 函数内部的200。综上: testB 函数内部的 a = 200 是定义了⼀个局部变量。
思考:如何在函数体内部修改全局变量?

a = 100
def testA():
	 print(a)
def testB():
	 # global 关键字声明a是全局变量
	 global a
	 a = 200
	 print(a)
testA() # 100
testB() # 200
print(f'全局变量a = {a}') # 全局变量a = 200

2.2 多函数程序执行流程

⼀般在实际开发过程中,⼀个程序往往由多个函数(后⾯知识中会讲解类)组成,并且多个函数共享某些数据,如下所示:

  • 共⽤全局变量
# 1.声明全局变量  2.定义两个函数  3.函数一修改全局变量,函数二访问全局变量
glo_num = 0

def test1():
    global glo_num
    glo_num = 100
    print(glo_num)
def test2():
    print(glo_num)

print(glo_num) # 0,因为修改的函数还没执行
test2()        # 0,因为修改的函数还没执行
test1()        # 100,调用函数A
test2()        # 100,先调用了函数1
print(glo_num) # 100,调用了函数1
  • 返回值作为参数传递
# 1.定义两个函数 2.函数一有返回值50,函数二把返回值50作为参数传入(定义函数二要有形参)
def test1():
    return 50
def test2(num):
    print(num)

# 先得到函数一的返回值,再把这个返回值传入到函数二
result = test1()
# print(result)

test2(result)#50

2.3 函数的返回值

需求:一个函数有两个返回值1 和 2
一个函数如果有多个return,不能都执行,只执行第一个return,无法做到一个函数多个返回值

"""
def return_num():
    return 1
    return 2  # return 自动结束当前程序

result = return_num()
print(result)
"""

# 一个函数多个返回值
def return_num():
    # return 1,2  # 返回的是元组
    # return 后面可以直接书写 元组 列表 字典 返回多个值
    # return (10,20)
    # return [10,30]
    return {'name':'wty','age':24}

result = return_num()
print(result)#{'name': 'wty', 'age': 24}

注意:

  • return a, b 写法,返回多个数据的时候,默认是元组类型。
  • return后⾯可以连接列表、元组或字典,以返回多个值。

2.4 函数的参数

  • 位置参数
    位置参数:调⽤函数时根据函数定义的参数位置来传递参数。
def user_info(name,age,gender):
    print(f'您的姓名是{name},您的年龄是{age},您的性别是{gender}')
    
# user_info('Tom',24,'男')
# user_info('Tom',24)  # 个数定义和传入不一致会报错
user_info('Tom','男',24)  # 顺序也要一致,否则无意义

注意:传递和定义参数的顺序及个数必须⼀致。

  • 关键字参数
    函数调⽤,通过“键=值”形式加以指定。可以让函数更加清晰、容易使⽤,同时也清除了参数的顺序需求。
# 函数调用,通过”键=值“形式加以指定,
def user_info(name,age,gender):
    print(f'您的姓名是{name},年龄是{age},性别是{gender}')

# 调用函数传参
user_info('ROSE',age = 20,gender='男')
user_info('wty',gender = '男',age = 24)  # 关键字参数之间不分先后顺序
# 位置参数必须写在关键字参数前面
# user_info(age= 20,gender = '男','TOm')  # 反例
# 'TOm'--位置参数,age= 20,gender = '男'--关键字参数
  • 缺省参数
def user_info(name,age,gender = '男'):
    print(f'您的姓名是{name},年龄是{age},性别是{gender}')

user_info('wty',20)  # 没有为缺省参数传值,表示使用默认值
user_info('wty',20,gender = '女') # 缺省参数修改
#您的姓名是wty,年龄是20,性别是男
#您的姓名是wty,年龄是20,性别是女

注意:函数调⽤时,如果为缺省参数传值则修改默认参数值;否则使⽤这个默认值。

  • 不定⻓参数
    不定⻓参数也叫可变参数。⽤于不确定调⽤的时候会传递多少个参数(不传参也可以)的场景。此时,可⽤包裹(packing)位置参数,或者包裹关键字参数,来进⾏参数传递,会显得⾮常⽅便。
    包裹位置传递
# 接收所有位置参数,返回一个元组
def user_info(*args):
    print(args)

user_info('TOM')#('TOM',)
user_info('TOM',20)#('TOM', 20)
user_info('TOM',20,110)#('TOM', 20, 110)
user_info()#()

包裹关键字传递

# 收集所有关键字参数,返回一个字典
def user_info(**kwargs):
    print(kwargs)

user_info()#{}
user_info(name = 'TOM')#{'name': 'TOM'}
user_info(name ='TOM',
age = 20)#{'name': 'TOM', 'age': 20}

综上:⽆论是包裹位置传递还是包裹关键字传递,都是⼀个组包的过程。

2.5 拆包和交换两个变量的值

拆包:元组

def return_num():
	 return 100, 200
num1, num2 = return_num()
print(num1) # 100
print(num2) # 200

拆包:字典

dict1 = {'name': 'TOM', 'age': 18} a, b = dict1
# 对字典进⾏拆包,取出来的是字典的key
print(a) # name
print(b) # age
print(dict1[a]) # TOM
print(dict1[b]) # 18

交换变量值
需求:有变量 a = 10 和 b = 20 ,交换两个变量的值。

a = 10
b = 20

# 方法一
"""
1.1 定义中间的第三变量,为了临时存储a或b的数据
1.2 把a的数据存储到c,做保存
1.3 把b的数据存储到a,a = 20
1.4 把c的数据赋值到b,b = 10
"""
"""
c = a
a = b
b = c
print(a)
print(b)
"""

# 方法二
a,b = 10,20
print(a)#10
print(b)#20
a,b = b,a
print(a)#20
print(b)#10

2.6 引用

在python中,值是靠引⽤来传递来的。
我们可以⽤ id() id() 来判断两个变量是否为同⼀个值的引⽤。 我们可以将id值理解为那块内存的地址标识。

# 可变和不可变
# 1.不可变
#  1.1声明变量保存整型数据,把这个数据赋值到另一个变量;id()检测两个变量的id值(内存的十进制)
a = 1
b = a

print(b)#1

# 发现a 和 b的id值相同的
print(id(a))#2595136694544
print(id(b))#2595136694544

# 修改a的数据检测id值
a = 2
print(b)#1

# 因为修改了a的数据,内存要开辟另一份存储数据2,id检测a和b的id值不同
print(id(a))#2595136694576
print(id(b))#2595136694544

# 2.可变数据:列表
aa =[10,20]
bb = aa
print(bb)#[10, 20]

print(id(aa))#2595142015104
print(id(bb))#2595142015104

引⽤当做实参

# 需求:引用是否可当做实参
"""
1. 定义函数:有形参
  1.1 访问打印形参看是否有数据
  1.2 访问形参的id
  1.3 改变形参的数据,查看这个形参并打印id,看id值是否相同
2. 调用函数 -- 把可变和不可变两种类型依次当做实参传入
"""
def test1(a):
    print(a)
    print(id(a))

    a += a
    print(a)
    print(id(a))

b = 100
test1(b)

c = [10,20]
test1(c)
"""
100
2060584699312
200
2060584702576

[10, 20]
2060587538560
[10, 20, 10, 20]
2060587538560
"""

2.7 可变和不可变类型

所谓可变类型与不可变类型是指:数据能够直接进⾏修改,如果能直接修改那么就是可变,否则是不可变

  • 可变类型
    列表
    字典
    集合
  • 不可变类型
    整型
    浮点型
    字符串
    元组