【问题标题】:Compiler Python, why are some wrong things overlooked?编译Python,为什么会忽略一些错误的东西?
【发布时间】:2012-09-16 14:30:29
【问题描述】:

我编写了一个 Python 例程,其中有一个错误:false 而不是 False。但是,在编译时没有发现它。该程序必须运行到此行才能通知错误行为。

为什么会这样? Python 解释器/编译器中的什么东西使它如此工作?

你有参考吗?

【问题讨论】:

  • false 是一个有效的变量名,而不是语法错误。
  • 要在 Python 2.7 中获得更多乐趣,请执行 True = 0; False = 1。欢闹随之而来。

标签: python compiler-construction compilation interpreter


【解决方案1】:

由于 Python 的动态特性,不可能在编译时检测到未定义的名称。只检查语法;如果语法没问题,编译器会生成字节码,Python 开始执行代码。

在给定的示例中,您将获得对全局名称 false 的引用。只有当字节码解释器试图真正访问这个全局名称时,才会报错。

为了说明,这里举个例子。你觉得下面的代码执行得好吗?

globals()["snyfr".decode("rot13")] = 17
x = false

确实如此,因为第一行动态生成了一个名为 false 的变量。

【讨论】:

    【解决方案2】:

    您可以将此视为解释器对于何时查找名称“懒惰”:它会尽可能晚地查找名称,因为程序的其他部分可能会在其已知变量字典中摆弄。

    考虑程序

    >>> def foo():
    ...     return false
    ... 
    >>> def bar():
    ...     global false
    ...     false = False
    ... 
    >>> foo()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in foo
    NameError: global name 'false' is not defined
    >>> bar()
    >>> foo()
    False
    

    请注意,对foo 的第一次调用引发了NameError,因为当时foo 运行Python 不知道false 是什么。但是bar随后修改了全局作用域并插入了false作为False的另一个名称。

    这种命名空间混淆允许人们在编写程序时具有极大的灵活性。当然,它还删除了许多限制性更强的语言可以为您检查的内容。

    【讨论】:

      猜你喜欢
      • 2017-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-27
      • 1970-01-01
      • 2011-11-27
      • 2020-09-03
      相关资源
      最近更新 更多