python中常见的错误与异常

本文详细介绍了Python中的错误与异常,包括语法错误、逻辑错误和运行时错误,以及如何通过try...except进行异常处理。此外,还深入探讨了Python函数的定义、调用、参数和作用域,包括形参、实参、默认值参数、不定参数以及内嵌函数等概念。通过学习,读者可以更好地理解Python中的错误处理和函数使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

错误与异常

错误

  • 语法错误(syntax error)
  • 逻辑错误(logic error)
  • 执行期间错误(runtime error)
for i in range(10)
    print(i)
    
# for i in range(10)
                     ^    
# SyntaxError: invalid syntax    

python的语法分析器完成,检测到错误所在文件和行号。以向上箭头标记错误位置。最后显示错误类型

当程序检测到一个错误,解释器就无法继续执行下去,抛出异常,终止程序。

异常

系统根据不同的错误,抛出不同的异常。

常见异常:
异常描述
NameError尝试访问一个没有申明的变量
ZeroDivisionError除数为 0
SyntaxError语法错误
IndexError索引超出序列范围
KeyError请求一个不存在的字典关键字
FileNotFoundError文件未发现错误(比如你要读的文件不存在)
AttributeError尝试访问未知的对象属性
ModuleNotFoundError模块未发现
IndentationError缩进
print(1/0)

#print(1/0)
#ZeroDivisionError: division by zero

a = 10
print(a)
print(b)

#10
#     print(b)
#NameError: name 'b' is not defined

li = [1, 2, 3]
print(li[3])

#    print(li[3])
#IndexError: list index out of range

dic = {'name': 'Tom'}
print(dic['age'])

#print(dic['age'])
#KeyError: 'age'

f = open('text.txt')

#f = open('text.txt')
#FileNotFoundError: [Errno 2] No such file or directory: 'text.txt'

class Car:
    pass
Car.color

# Car.color
#AttributeError: type object 'Car' has no attribute 'color'

异常处理

程序一旦发生错误,程序就无法继续运行。

为了使程序健壮,可做相关异常处理。

try … except …

try:
    try_statements
except [exceptionType [as identifier]]:
    except_statements
[else:
    else_statements]    
[finally:
    finally_statements]     

例:

try:
 X = eval(input('请输入被除数x:\t'))
 Y = eval(input('请输入除数y:\t'))
 Z = X / Y
'''
except ZeroDivisionError:
 print("除数不能为0.")
except NameError:
 print("先检查变量是否赋值。")
'''
except Exception as e:
print(e.args)
'''
except (ZeroDivisionError, NameError, TypeError) as e:
 print(e.args)
 print()
'''
else:
 print("未捕捉到异常,X/Y =", Z)
finally:
 print("离开try ... except 模块。")

raise(触发异常)

除了系统抛出的异常,我们可以用raise语句自己触发异常。

格式:

raise [Exception [, args [, traceback]]]

  • Exception:异常类型
  • args:我们自己提供的异常参数
  • traceback:可选,如果存在,跟踪异常对象。
raise NameError("Sorry, Error occurs")

# raise NameError("Sorry, Error occurs")
#NameError: Sorry, Error occurs

#将这个异常处理
try:
    raise NameError("Sorry, Error occurs")
except NameError:
    print("异常已处理。")
    
#异常已处理。    

assert(断言)

assert condition

逻辑上相当于:

if not condition:
    raise AssertionError()

为断言添加一个异常参数

assert expression [, args]

arguments

函数

引子:

算1-15,23-36,55-68的和

def sum_num(i1, i2):
    s = 0
    for i in range(i1, i2 + 1):
        s += i
    return s


print(sum_num(1, 15))
print(sum_num(23, 36))
print(sum_num(55, 68))

'''
120
413
861
'''

程序而言:函数就是对程序逻辑进行结构化或者过程化的一种编程方法。

built-in function 内置函数 —> BIF

函数的定义

声明函数的一般形式:

def function_name(arg1,arg2,…,argn):

​ ‘’’ statements ‘’’

​ func_statements

​ return value

说明如下:

1.函数代码块以 def 关键词开头,后接函数标识符名称和小括号 ()。

2.任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。

3.函数的第一行语句可以选择性地使用文档字符串----用于存放函数说明。

4.函数内容以冒号起始,并且缩进。

5.return [表达式] 结束函数,选择性的返回一个值给调用方。不带表达式的return相当于返回 None。

其中参数列表和返回值不是必须的,return后也可以不跟返回值,甚至连 return也没有。

对于return后没有返回值的和没有return语句的函数都会返回None值

有些函数可能既不需要传递参数,也没有返回值。

没有参数时,包含参数的圆括号也必须写上,圆括号后也必须有“:”。

函数的调用

函数文档说明

函数参数

  • 不含参函数
  • 含参函数
    • 顺序
函数返回值
函数的参数种类

形参和实参

  • 形参
    • 只有在调用时才分配内存单元。调用结束后,即释放所分配的内存单元。因此,形参只在内部有效,函数调用结束返回主函数后则不能再使用该形参变量。
  • 实参
    • 实参就是一个确定的值,能够传递给形参。
      • 作为位置参数或者关键字参数传递。
def usr_manage(name, age, job, hobby):
    print('用户管理系统'.center(16, '-'))
    print("\tName:\t", name)
    print("\tAge:\t", age)
    print("\tJob:\t", job)
    print("\tHobby:", hobby)
    print("用户管理系统".center(16, '-'))


usr_manage("Tom", 20, "IT", "Coding")
usr_manage("Jim", 21, "Student", "Reading")

只传递实参,位置一一对应 —> 位置参数

使用位置参数时和函数头定义的形象在顺序,个数以及类型上匹配。

  • 关键字参数
def usr_manage(name, age, job, hobby="Trip"):
    print('用户管理系统'.center(16, '-'))
    print("\tName:\t", name)
    print("\tAge:\t", age)
    print("\tJob:\t", job)
    print("\tHobby:", hobby)
    print("用户管理系统".center(16, '-'))


usr_manage("Jack", 22, hobby="Coding", job="Student")
usr_manage("Tom", 20, "IT", "Coding")
usr_manage("Jim", 21, "Student", "Reading")

默认值参数,关键字参数,必须放置于位置参数后。

不定参数

在python中不定参数主要是指*args和**kwargs两个魔法变量。

他们俩主要是用于函数定义,我们可以将不定数量的参数传递给一个函数。

  • *args用来接收任意非键值对的任意数量的参数列表给函数。
def uncertain_para(para, para2, *args):
    print("普通位置参数:", para, para2)
    print("不定参数:", args)
    print(type(args))


uncertain_para(1, 2, 3, 4, 'a', 'b')
uncertain_para([1, 2, 3], "ab", "cd", "ef")

'''
普通位置参数: 1, 2
不定参数: (3, 4, 'a', 'b')
<class 'tuple'>
普通位置参数: [1, 2, 3] ab
不定参数: (cd', 'ef')
<class 'tuple'>
'''
  • **kwargs 用来接收任意不定长度的键值对列表给函数
def un_para_key(**kwargs):
    print(kwargs)
    print(type(kwargs))


un_para_key(a=1, b=2, c=3)

#{'a': 1, 'b': 2, 'c': 3}
#<class 'dict'>

**args返回元组,*kwargs返回字典

def un_para_key(x, y, *z, **kwargs):
    print(x, y, z)
    print(kwargs)
    print(type(kwargs))


un_para_key(1, 2, 3, 4, 5, 'a', 'b', a=1, b=2, c=3)

'''
1 2 (3, 4, 5, 'a', 'b')
{'a': 1, 'b': 2, 'c': 3}
<class 'dict'>
'''
def func(p):
    digit = 0
    alpha = 0
    space = 0
    others = 0
    for i in p:
        if i.isdigit():
            digit += 1
        elif i.isalpha():
            alpha += 1
        elif i.isspace():
            space += 1
        else:
            others += 1
    return digit, alpha, space, others


print(func('123 abc %^&'))

#(3, 3, 2, 3)

函数的引用

def foo():
    print("in foo()")
    bar()


def bar():
    print("in bar()")


foo()


#in foo()
#in bar()
函数属性

函数属性是python中另外一个使用了句点属性标识并拥有名字空间的领域。

def foo():
    'foo() --- Properly created doc string.'


def bar():
    pass


bar.__doc__ = "Oops, forget the doc str above"
bar.version = 0.1
内嵌函数

作用域

bar()整个函数都处于外部foo()函数的作用域里(foo()是我们可以从外部访问的一个对象区域)。除了在foo()内部,其他地方无法对bar()进行调用。

变量作用域

作用域的产生

就作用域而言,python和C有很大差别,只有当变量在module,Class,函数中定义的时候,才会有作用域的概念。

def foo():
    a = "foo"
    print(a)
foo()
print(a)

在作用域中定义的变量,一般只在作用域内有效。需要注意的是,在if-elif-else,for-else,while-else,try-except(else-finally)等关键字的语句块中不会产生作用域。

作用于的类型

Python中,使用一个变量时并不要求需要预先声明它。但真正使用的时候,他必须绑定到某个内存对象(被定义,赋值)。这种变量名的绑定将在当前作用域引入新的变量,同时屏蔽外层作用域中的同名变量。

  • 局部作用域(locale — L)

  • 嵌套作用域(enclosing — E)

    • E 也包含在def 关键字中,E和L是相对的,E相对于跟上层的函数而言也是L。与L的区别在于,对于一个函数而言,L是定义在此函数内部的局部作用域。
    • 主要为了实现Python的闭包,而增加的实现。
  • 全局作用域(Global — G)

    即在模块层次中定义的变量。模块顶层申明的变量具有全局作用域。从外部看,模块的全局变量就是一个模块对象的属性。

  • 内置作用域(built-in — B)

    • 系统固定模块中定义的变量。

搜索变量名的优先级:局部作用域 > 嵌套作用域 > 全局作用域 > 内置作用域

全局变量和局部变量

gbl_str = "foo"
def foo():
    loc_str() = "bar"
    return gbl_str + loc_str
print(foo())
print(gbl_str)
print(loc_str)

#先局部,后全局
def foo():
    a = 666
    print("foo(), 修改前a:\t", a)
    a = 888
    print("foo(), 修改后a:\t", a)

def bar():
    a = 6688
    print("bar(), a:\t", a)
foo()
bar()

'''
foo(), 修改前a:	 666
foo(), 修改后a:	 888
bar(), a:	 6688
'''

若局部和全局名一样,会报错(会先搜索局部),得将局部名改为和全局名不一样才能正常运行。

a = 6688
def foo():
    # a = 666
    print("foo(), 修改前a:\t", a)
    b = 888
    print("foo(), 修改后a:\t", a)

def bar():
    # a = 6688
    print("bar(), a:\t", a)
foo()
bar()

'''
foo(), 修改前a:	 6688
foo(), 修改后a:	 6688
bar(), a:	 6688
'''
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值