为什么不';";提高;及;del";Python中的函数?

为什么不';";提高;及;del";Python中的函数?,python,function,python-3.x,structure,Python,Function,Python 3.x,Structure,从Python2到Python3的一个基本变化是使print成为一个函数——对于我来说,考虑到它的结构,这个函数非常有意义。为什么raise和del语句不起作用?特别是在raise的情况下,它似乎是在接受一个参数并用它做一些事情,就像函数一样。有一个合理的列表,说明了为什么print成为函数。在这五个原因中,(国际海事组织)最相关的一个是: 打印是唯一具有专用语句的应用程序级功能 正如Alex Martelli在这里所解释的: Python语句是Python编译器必须特别注意的事情——它们可能会

从Python2到Python3的一个基本变化是使
print
成为一个函数——对于我来说,考虑到它的结构,这个函数非常有意义。为什么
raise
del
语句不起作用?特别是在
raise
的情况下,它似乎是在接受一个参数并用它做一些事情,就像函数一样。

有一个合理的列表,说明了为什么
print
成为函数。在这五个原因中,(国际海事组织)最相关的一个是:

打印是唯一具有专用语句的应用程序级功能

正如Alex Martelli在这里所解释的:

Python语句是Python编译器必须特别注意的事情——它们可能会改变名称的绑定,可能会改变控制流,和/或在某些情况下可能需要从生成的字节码中完全删除(后者适用于断言)。print是Python 2中这个断言的唯一例外;通过将其从语句列表中删除,Python3删除了一个异常,使一般断言“just hold”,因此是一种更常规的语言


del
raise
显然改变了名称的绑定/改变了控制流,因此它们都是正常的

raise
del
与功能截然不同,原因各不相同:

  • raise
    退出当前执行流;字节码解释的正常流程中断,堆栈展开,直到找到下一个异常处理程序。函数不能这样做,而是创建一个新的堆栈帧

  • del
    不能是函数,因为必须指定特定目标;不能只使用任何表达式,删除的内容取决于给定的语法;如果使用subscription,则会删除容器中给定的元素,或者从当前命名空间中删除名称。要删除的正确命名空间还取决于已删除名称的范围。见:

    函数不能从父命名空间中删除项,也不能区分订阅表达式或直接引用的结果。您向函数传递对象,但向
    del
    语句传递名称和上下文(可能是在删除本地或全局名称时由解释器传递)

另一方面,
print
,不需要与当前名称空间或堆栈框架有特殊的关系,也不需要特殊的语法约束来完成它的工作。它纯粹是应用程序级别的功能。函数和解释器都可以访问全局
sys.stdout
引用。因此,它不需要是一个语句,通过将其移动到函数,可以获得额外的好处,例如能够覆盖它的行为,并在Python版本中更快地对其进行创新

请注意,
raise
语句的部分已移到应用程序级代码;在Python 2中,您可以通过以下方式将回溯附加到引发的异常:

raise ExceptionClass, exception_value, traceback_object
在Python 3中,将回溯附加到异常已移动到异常本身:

raise Exception("foo occurred").with_traceback(tracebackobj)
raise Exception("foo occurred").with_traceback(tracebackobj)