python第三天学习

Python学习

python函数

函数的创建

  • 格式:

def 函数名([输入参数]):

​ 函数体

​ [return xxx]

函数的使用

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


print(calc(10, 20))  # 30

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZEKXqZ9g-1654523798082)( https://imgs3.loukky.com/imgs/2022/06/06/179a58f684f8f585.png )]

函数的参数传递

  • 位置实参:根据形参对应的位置进行实参传递
def calc(a, b):  # a,b 称为形式参数,简称形参,形参的位置在函数定义处
    return a - b


# 10,50 是实际参数的值,简称 实参,实参的位置是函数调用处
print(calc(10, 50))  # -40
  • 关键字实参:根据形参名称来实参传递
def calc(a, b):  # a,b 称为形式参数,简称形参,形参的位置在函数定义处
    return a - b

# 等号左边的变量称为 关键字参数,即b,a都是关键字参数
print(calc(b=10, a=50))  # 40

参数传递的内存分析图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FQ57e2Yb-1654523798084)( https://imgs3.loukky.com/imgs/2022/06/06/36f0b79eafd83e04.png )]

在函数的参数传递的过程中:

  • 如果传递的是不可变对象,则在函数体中的操作,不会对不可变对象造成影响,即上述的n1依旧是11

  • 如果传递的是可变对象,比如列表、字典、集合等,则函数体中对可变对象的操作会使可变对象发生改变,即完成函数调用后,n2变成了[22,33,44,10]

函数的返回值

  • 函数没有返回值,return可以不写
  • 函数返回一个值时,直接返回该值,返回类型为该值的类型
  • 函数返回多个值时,结果为元组
def calc(a, b):
    a = a - b
    return a - b, a + b


print(calc(10, 20))  # (-30,10)
print(type(calc(10, 20)))  # <class 'tuple'>

函数的参数定义

函数定义形参的默认值

当传递参数时,没有给设置了默认值的形参传递值时,该形参使用设置好的默认值,如果传递了值,则使用传过来的值

def calc(a, b=30):
    return a + b


print(calc(10))  # 40
print(calc(10, 50))  # 60
个数可变的位置参数
  • 定义函数时,可能无法事先确定传递的 位置实参 的个数时,使用可变的位置参数
  • 使用 * 定义 个数可变的位置形参
  • 结果为一个元组
  • 可变的位置参数只能有一个,如 def func(*args,*a) 这样子定义函数是错误的
def func1(*args):
    print(args)


func1(10)  # (10,)
func1(10, 20)  # (10, 20)
func1(10, 20, 30)  # (10, 20, 30)
个数可变的关键字参数
  • 定义函数时,无法事先确定传递的 关键字实参 的个数时,使用可变的关键字形参
  • 使用 ** 定义 个数可变的关键字形参
  • 结果为一个字典
  • 可变的关键字参数只能有一个,如 def func(**args,**a) 这样子定义函数是错误的
def func1(**args):
    print(args)


func1(a=10)  # {'a': 10}
func1(a=10, b=20)  # {'a': 10, 'b': 20}
func1(a=10, b=20, c=30)  # {'a': 10, 'b': 20, 'c': 30}

个数可变的位置参数和个数可变的关键字参数可以搭配使用,但是个数可变的位置参数需要在个数可变的关键字参数之前,如:def func2(*args1,**args2): 这样子是可行的,但是 def func2(**args1,*args2): 是不可行的

将序列中的每个元素都转换成位置实参
  • 使用 *
def func1(a, b, c):
    print('a', a)
    print('b', b)
    print('c', c)


func1(10, 20, 30)
'''
a 10
b 20
c 30
'''
list1 = [11, 22, 33]
# func1(list1)        TypeError: func1() missing 2 required positional arguments: 'b' and 'c'
func1(*list1)
'''
a 11
b 22
c 33
'''
将字典中的每个键值对都转换成关键字实参
  • 使用 **
def func1(a, b, c):
    print('a', a)
    print('b', b)
    print('c', c)


func1(a=10, b=20, c=30)
'''
a 10
b 20
c 30
'''
dict1 = {'c': 10, 'b': 20, 'a': 30}
# func1(dict1)        TypeError: func1() missing 2 required positional arguments: 'b' and 'c'
func1(**dict1)
'''
a 30
b 20
c 10
'''
限制必须使用关键字传递
  • 使用 *
def func1(a, *, b, c):      # 这里的 * 表示,* 号之后的参数必须采用关键字参数传递,* 之前采用位置或者关键字都行
    print('a', a)
    print('b', b)
    print('c', c)


func1(a=10, b=20, c=30)
'''
a 10
b 20
c 30
'''
# func1(10,20,c=30)       TypeError: func1() takes 1 positional argument but 2 positional arguments (and 1 keyword-only argument) were given
func1(10, b=20, c=30)
'''
a 10
b 20
c 30
'''

传递参数时,必须是先位置参数,再关键字参数

比如说:函数定义时: def func1(a,b,c):

函数调用时: func1(10,20,c=30) 这种是正确的

func1(a=10,20,c=30) 这种是错误的

可行的函数定义格式:
  • def func(a,b,*,c,d):
  • def func(a,b,*,c,d,**args):
  • def func(a,b=10,*args1,**args2):
变量的作用域
  • 变量的作用域是指 程序能够访问该变量的区域
  • 根据变量被访问的范围,可分为:
    • 局部变量
      • 在函数内定义并使用的变量,只在函数内部有效
      • 局部变量使用global声明,这个变量就会就成全局变量
    • 全局变量
      • 函数体外定义的变量,可作用于函数内外
name = 'wwj'  # 全局变量,程序任意地方都访问得到

def func1():
    age = 20  # 局部变量,只有该函数的方法体内才访问的到
    global sex
    sex = '男'
    print(name, '\t', age)


func1()  # wwj 	 20
# print(age) age为局部变量,访问不到
print(sex)  # 男         sex 被global声明,变成全局变量

递归函数

  • 什么是递归函数
    • 如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数
  • 递归函数的组成部分
    • 递归调用与递归终止条件
  • 递归的调用过程
    • 每递归调用一次函数,都会在栈内存分配一个栈帧,
    • 每执行完一次函数,都会释放相应的空间
  • 递归的优缺点
    • 缺点:占用内存多,效率低下
    • 优点:思路和代码简单

练习题:使用递归来计算 n 的阶乘

def func(n):
    if n == 1:
        return 1
    else:
        return n * func(n - 1)


print(func(6))  # 720

练习题:斐波拉契数列 1、1、2、3、5、8、13…

def func(n):
    if n == 1:
        return 1
    elif n == 2:
        return 1
    else:
        return func(n-2)+func(n-1)


print(func(6))  # 8

Bug常见类型

  • 漏了末尾的冒号,如if语句,循环语句,else子句等
  • 缩进错误,该缩进的没缩进,不该缩进的瞎缩进
  • 把英文符号写成中文符号,比如说:引号,冒号,括号
  • 字符串拼接的时候,把字符串和数字拼在一起
  • 没有定义变量,比如说while的循环条件的变量
  • “==” 比较运算符和 “=” 赋值运算符的混用
  • 索引越界异常 IndexError
  • append() 方法添加元素,一次只能添加一个元素

python的异常处理机制

一般,当程序出现异常,程序立刻停止运行,但是也有方法处理异常,保证当异常发生时,捕获异常并对其进行处理,确保了程序的正常运行

try…except…结构

单个except示意图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gcaYMkqU-1654523798085)( https://imgs3.loukky.com/imgs/2022/06/06/2a8fbde6b2ed5bd3.png )]

def func(a, b):
    return a / b


try:
    print(func(10, 0))  # 除数不能为0!
except ZeroDivisionError:
    print('除数不能为0!')

当可能有多个异常存在时,

捕获异常的顺序按照先子类后父亲类的顺序,即先捕获小的比较细节的异常,再捕获大的笼统的异常,为了避免遗漏可能出现的异常,可以在最后增加BaseException

多个except示意图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YgKc4Oy5-1654523798086)( https://imgs3.loukky.com/imgs/2022/06/06/fc2eebd29f56f195.png )]

def func(aa, bb):
    return aa / bb


try:
    a = int(input("请输入第一个数:\t"))
    b = int(input("请输入第二个数:\t"))
    print(func(a, b))
except ZeroDivisionError:
    print('除数不能为0!')
except ValueError:
    print('只能输入数字!')
except BaseException:
    print('存在异常,请及时处理')

try…except…else…结构

如果try块中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块

def func(aa, bb):
    return aa / bb


try:
    a = int(input("请输入第一个数:\t"))
    b = int(input("请输入第二个数:\t"))
    result = func(a, b)
except ZeroDivisionError:
    print('除数不能为0!')
else:
    print('结果为:\t', result)

try…except…else…finally…结构

finally块无论是否发生异常都会被执行,能常用来释放try块中申请的资源

def func(aa, bb):
    return aa / bb


try:
    a = int(input("请输入第一个数:\t"))
    b = int(input("请输入第二个数:\t"))
    result = func(a, b)
except BaseException as e:
    print('有异常产生!')
    print(e)
else:
    print('结果为:\t', result)
finally:
    print('程序结束!')

python常见的异常类型

  • ZeroDivisionError 除数为0所触发的异常
  • IndexError 索引越界所触发的异常
  • KeyError 映射中没有所指定的Key,比如根据字典中不存在的key来取value
  • NameError 未声明/初始化对象
  • SyntaxError Python语法异常
  • ValueError 传入无效的参数/值

traceback模块

  • 使用traceback模块打印异常信息
import traceback
try:
    print('-----------')
    print(10 / 0)
except:
    # 可以自行捕获异常,并对其进行处理,也可以这样子简单的输出异常信息,程序不会中断
    traceback.print_exc()

print('hello')

pycharm的调试

  • 设置断点
  • Debug运行
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值