【问题标题】:How python interns strings in interactive interpreter vs jupyter notebookpython如何在交互式解释器与jupyter笔记本中实习字符串
【发布时间】:2020-11-18 00:27:32
【问题描述】:

我试图了解什么时候 python 实习生常量,什么时候不。我正在为这个问题使用 python 3.8.5。据我了解,在 python 3.7 之后,python 从 peephole 优化更改为 AST 优化器,并且更长的字符串现在被实习了。

我以为这一切都在我的掌控之中,直到我尝试在 jupyter notebook 和交互式解释器中运行相同的命令——在相同的 conda 环境和相同版本的 python 中。

>>> sys.version
'3.8.5 (default, Sep  4 2020, 02:22:02) \n[Clang 10.0.0 ]'

>>> "AvocadoAvocadoAvocadoAvocadoAvocado !" is "AvocadoAvocadoAvocadoAvocadoAvocado !"
<stdin>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
False

在 Jupyter Notebooks 中

import sys
sys.version

给予

'3.8.5 (default, Sep  4 2020, 02:22:02) \n[Clang 10.0.0 ]'
"AvocadoAvocadoAvocadoAvocadoAvocado !" is "AvocadoAvocadoAvocadoAvocadoAvocado !"

给予

<>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
<>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
<ipython-input-6-2414f185945a>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
  "AvocadoAvocadoAvocadoAvocadoAvocado !" is "AvocadoAvocadoAvocadoAvocadoAvocado !"
True

我无法弄清楚为什么解释器中的结果为 False 而笔记本中的结果为 True。我还想知道为什么笔记本中有三个警告,而解释器中只有一个,这是否包含导致结果不同的任何线索。

为什么我在交互式解释器中得到 False 而在 Jupyter Notebooks 中得到 True?

【问题讨论】:

  • @Boris。我完全理解这一点,以及实习在 Jupyter Notebooks 中的工作原理以及如何强制静态值被实习。我不明白为什么同一个命令在解释器和 Jupyter Notebooks 中的行为不同。
  • 我无法在 3.8.2 中重现此行为。如果字符串确实相等,即使字符串相当长(超过 200 个字符),我也会得到 True
  • This 看起来很可能是 ipython 不同结果的答案(基本上归结为在优化器达到成为PyObject)

标签: python jupyter-notebook


【解决方案1】:

python(和其他语言)中有很多东西看起来似乎可以工作,但与它们应该如何工作的定义背道而驰。对象身份就是其中之一。 is 关键字的目的不是比较某物的值,而是测试两个变量是否引用同一个底层对象。虽然如果它们是同一个对象,那么值也必须相等,这似乎是有道理的,但反过来说,这种说法根本不正确。这有时会起作用(如您所见)而不会引发异常,但它不是python的定义功能。这些是“依赖于实现”的东西,并且永远不能保证给出正确甚至稳定的结果。

显然,ipython 不会像通过内置 REPL 提交的方式向 cpython 二进制文件提交代码块:https://github.com/satwikkansal/wtfpython/issues/100#issuecomment-549171287

我认为这是为了减少前端在发送多行代码时必须发送到内核的消息数量。在这方面,我希望从命令行执行 .py 文件的行为会更好地匹配您从 ipython 获得的结果。

按照这些思路,有时可以在删除后但在垃圾回收之前恢复对象,因为id 函数的实现返回可与@987654324 一起使用的对象的内存位置@ 构造一个新的PyObject。这是一种在代码中引入错误和不稳定性的方法。如果出于某种原因,id 被切换到每个分配项目的简单计数器,(也许你想防止泄漏有关进程内存空间的任何信息)这将立即中断。

【讨论】:

  • 该问题链接包含答案。感谢您找到它!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-04
  • 2020-02-26
  • 2021-01-27
  • 2017-03-22
  • 2018-01-05
  • 2020-07-19
  • 1970-01-01
相关资源
最近更新 更多