18. 错误和异常——Python官网语法摘录

本文深入探讨了Python中的异常处理机制,包括异常的一般式、except子句的使用、异常类的定义与抛出,以及如何利用else子句和异常参数进行更精细的错误管理。

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

1. 异常一般式
>>> while True:
...     try:
...         x = int(input("Please enter a number: "))
...         break
...     except ValueError:
...         print("Oops!  That was no valid number.  Try again...")
...

except 可以多行

2. except 子句的元组
... except (RuntimeError, TypeError, NameError):
...     pass

异常类

class B(Exception):
    pass

class C(B):
    pass

class D(C):
    pass

for cls in [B, C, D]:
    try:
        raise cls()
    except D:
        print("D")
    except C:
        print("C")
    except B:
        print("B")

如果 except 子句被颠倒(把 except B 放到第一个),它将打印 B,B,B — 即第一个匹配的 except 子句被触发。

最后的 except 子句可以省略异常名,以用作通配符。但请谨慎使用,因为以这种方式很容易掩盖真正的编程错误!它还可用于打印错误消息,然后重新引发异常(同样允许调用者处理异常)

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise
3. else 子句

else 子句必须放在所有的 except 子句后面。作为在try 子句不引发异常时必须执行的代码

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except OSError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()
4. 异常参数

except 子句可以在异常名称后面指定一个变量。这个变量和一个异常实例绑定,它的参数存储在 instance.args 中。为了方便起见,异常实例定义了 str() ,因此可以直接打印参数而无需引用 .args 。也可以在抛出之前首先实例化异常,并根据需要向其添加任何属性。

>>> try:
...     raise Exception('spam', 'eggs')
... except Exception as inst:
...     print(type(inst))    # the exception instance
...     print(inst.args)     # arguments stored in .args
...     print(inst)          # __str__ allows args to be printed directly,
...                          # but may be overridden in exception subclasses
...     x, y = inst.args     # unpack args
...     print('x =', x)
...     print('y =', y)
...
<class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs

如果异常有参数,则它们将作为未处理异常的消息的最后一部分打印。

>>> def this_fails():
...     x = 1/0
...
>>> try:
...     this_fails()
... except ZeroDivisionError as err:
...     print('Handling run-time error:', err)
...
Handling run-time error: division by zero
4. 抛出异常

raise 语句允许程序员强制发生指定的异常。

>>> raise NameError('HiThere')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: HiThere

raise 唯一的参数就是要抛出的异常。这个参数必须是一个异常实例或者是一个异常类(派生自 Exception 的类)。如果传递的是一个异常类,它将通过调用没有参数的构造函数来隐式实例化。

raise ValueError  # shorthand for 'raise ValueError()'

如果你需要确定是否引发了异常但不打算处理它,则可以使用更简单的 raise 语句形式重新引发异常

>>> try:
...     raise NameError('HiThere')
... except NameError:
...     print('An exception flew by!')
...     raise
...
An exception flew by!
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
NameError: HiThere

未完结。。。。。。。。。。

————Blueicex 2020/07/19 18:45 blueice1980@126.com

### Python 类实例化过程 在 Python 中,类的实例化是指通过已定义好的类来创建具体的对象的过程。这一过程中涉及的关键部分包括 `__init__()` 方法其他内置机制。 #### 1. **`__new__()` `__init__()` 的作用** - 当一个类被实例化时,Python 首先会调用 `__new__()` 方法来分配内存并返回一个新的对象[^1]。 - 返回的新对象随后会被传递给 `__init__()` 方法作为第一个参数(即 `self`)。在这个阶段,初始化工作会在 `__init__()` 方法中完成,比如设置初始状态或绑定属性到新创建的对象上[^1]。 #### 2. **示例代码展示** 下面是一段简单的例子展示了如何定义一个具有基本功能的学生类,并对其进行实例化: ```python class Student: def __init__(self, name, age, school): self.name = name # 学生姓名 self.age = age # 年龄 self.school = school # 所在学校 def print_info(self): """打印学生的个人信息""" print(f"Name: {self.name}, Age: {self.age}, School: {self.school}") @classmethod def get_default_school(cls): """获取默认学校名称""" return "NoSchool" # 创建Student类的一个实例 student_instance = Student("Alice", 20, "XYZ University") # 调用实例方法 student_instance.print_info() ``` 这段代码说明了几个要点: - 使用 `__init__()` 初始化学生的名字、年龄所属学校的值; - 定义了一个普通的实例方法 `print_info()` 来显示这些数据; - 还有一个装饰器标记的类方法 `@classmethod`, 可以不依赖具体某个实例而直接由类本身调用来获得某些固定的信息[^2]。 --- ### 如何调用类中的函数? 对于已经成功实例化的对象来说,可以通过点号`.`操作符去访问其内部的方法或者变量。 #### 实例方法调用 如果要调用的是普通实例方法,则只需指定好对应的实例名即可实现正常调用: ```python student_instance.print_info() # 输出结果将是 Name: Alice, Age: 20, School: XYZ University ``` 这里我们看到的就是典型的实例方法调用方式——借助之前建立起来的那个特定个体(student_instance),进而执行其中封装的行为逻辑(print_info())[^1]。 #### 类方法与静态方法调用 除了常规意义上的实例方法之外,在面向对象设计里还存在另外两种特殊的成员形式—类别专属的操作接口(也就是所谓的“类方法”)以及完全独立于任何实体存在的辅助工具型服务提供者们(亦称为“静态方法”). 关于前者(`@classmethod`),它允许开发者即使没有实际制造出任何一个真实世界的映射物也能顺利完成预期的任务;而对于后者而言(@staticmethod), 则更是进一步摆脱掉了所有跟当前上下文中所关联的具体事物之间的联系约束条件限制. 例如上面提到过的那个用于设定缺省值得getter函数(get_default_school): ```python default_school_name = Student.get_default_school() print(default_school_name) # NoSchool ``` 此处在无需构建任何单独学员记录的前提下就能够轻松取得预设配置项的内容啦! 同样地,@staticmethod也可以按照相似的方式来进行处理只不过由于缺乏隐含接收者的缘故所以在签名定义的时候不需要额外声明诸如cls之类的占位符而已.[^2] --- ### C++环境中对Python类的支持情况简介 值得注意的一点在于跨语言协作场景下同样能够很好地支持这种基于OO思想构建出来的结构体单元。比如说利用嵌入式脚本技术把整个解释引擎集成进去之后就可以很方便地操纵那些预先准备完毕后的外部资源文件里面的组件元素咯~ 下面给出了一小段示范性的片段演示怎样从CPP端发起请求从而激活目标模块内的相应动作响应链路:[^3]: ```cpp // 假定m代表加载成功的module module object pointer. PyObject* type_py_class = PyObject_GetAttrString(m, "TypePy"); if (!type_py_class){ throw std::runtime_error("Failed to retrieve TypePy class."); } // Instantiate the python class equivalent of calling its constructor/__init__ PyObject* instance = PyObject_CallObject(type_py_class, nullptr); if(!instance){ PyErr_Print(); throw std::runtime_error("Instance creation failed."); } // Invoke member function 'test' on newly created python object PyObject_CallMethod(instance,"test",nullptr); // Clean up resources properly after usage completed. Py_DECREF(instance); Py_DECREF(type_py_class); ``` 以上摘录清楚表明即便是在完全不同语法体系下的应用程序框架之中依旧可以无缝衔接彼此之间互相配合共同作业的能力表现出来哦~ ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值