Python:使用 PyCharm 和 IDLE/python 时的不同结果 [英] Python: Different results when using PyCharm and IDLE/python

查看:42
本文介绍了Python:使用 PyCharm 和 IDLE/python 时的不同结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚读到is 运算符的意外结果",这是因为 Python 缓存数字介于 -5 和 256 之间.

这里讨论过:是"运算符对整数的行为异常

这里:是"和id"在 Python 3.5 中

当我运行其中给出的示例之一时,我在 Python Idle 和 Python IDE 之间得到不同的结果(我使用的是 Jetbrains Pycharm 专业版 - 5.0.4).

当使用 Python IDLE 时,结果如下:

a = 1000b = 1000print (a is b) # 打印 False

当使用 Pycharm 5.0.4 时,结果如下:

a = 1000b = 1000print (a is b) # 打印 True

这怎么可能?我已经重新检查过,我的项目的 Python-Interpreter 在这两种情况下都是完全相同的(都是 Python 3.5.1).不知道这是否是我做错了什么,我希望有人能解释一下.

我知道 'a' 是 'b' == true 如果 id(a) == id(b),并且您可以像评论中提到的一些人一样检查它.也许我应该更清楚一点,我不明白 IDE 怎么会有不同的行为?我认为(请纠正我,因为我似乎错了)IDE 只是一个使用外部编译器/解释器的用户友好环境,这就是为什么这些独立于那些 IDE(例如,pycharm 支持不仅是 Python,我还可以使用 C 编译器或 Java 等运行 Eclipse(所有这些都不是 IDE 的一部分).

谢谢,阿隆.

解决方案

这是因为 LOAD_CONST 字节码有效:

<块引用>

co_consts[consti] 推入堆栈.

由于整数被存储为常量,因此在相同上下文中对相同整数的赋值将产生完全相同的结果,我们可以看到对 LOAD_CONST 的争论是 0对于 a 和 b:

<预><代码>>>>导入dis>>>dis.dis("a = 1000 ; b = 1000")1 0 负载常量 0 (1000)3 STORE_NAME 0(一)6 负载常数 0 (1000)9 STORE_NAME 1 (b)12 LOAD_CONST 1(无)15 返回值# ^ 这是参数

在交互式会话中,每个命令都是单独编译的(以便它们可以单独执行),因此常量会有所不同:

<预><代码>>>>code1 = compile("a = 1000","","exec")>>>code2 = compile("a = 1000","","exec")>>>code1.co_consts,code2.co_consts((1000,无),(1000,无))>>>code1.co_consts[0] 是 code2.co_consts[0]错误的

同样,函数中的常数总是相同的,但与其他函数中的常数不同:

def f():返回 1000定义 g():返回 1000 #不同的代码对象!!#这些都有效断言 f() 是 f()断言 g() 是 g()断言 f() 不是 g()断言 f() 不是 1000 并且 g() 不是 1000

还请注意,正如 @AniMenon 指出的,从 -5 到 256 的数字是用于优化的单例,所以相同不适用于该范围内的数字.

I was just reading about the 'unexpected result of is operator' which happens because Python cache numbers between -5 and 256.

This was discussed here: "is" operator behaves unexpectedly with integers

and here: "is" and "id" in Python 3.5

When I run one of the examples given there, I get different results between Python Idle and Python IDE (I'm using Jetbrains Pycharm professional edition - 5.0.4).

When using Python IDLE this is the result:

a = 1000
b = 1000
print (a is b) # prints False

when using Pycharm 5.0.4 this is the result:

a = 1000
b = 1000
print (a is b) # prints True

how could this be? I've rechecked, and my project's Python-Interpreter is exactly the same in both cases (both are Python 3.5.1). Not sure if this is something I've done wrong, and I was hoping if someone could explain this.

Edit:

I know 'a' is 'b' == true iff id(a) == id(b), and that you can check it like some of you mentioned in the comments. Perhaps I should have been more clear, what I don't understand is how could it be that an IDE has different behavior? I thought (and please, correct me, as it seems I'm wrong) that an IDE is just a user-friendly environment that uses external compilers / interpreters, and this is why these are independent of those IDE's (for instance, pycharm supports not only Python, and I could run Eclipse with C compiler, or Java etc. (all of which are not parts of the IDE).

Thanks, Alon.

解决方案

This is because of how LOAD_CONST byte code works:

Pushes co_consts[consti] onto the stack.

Since integers are stored as constants then assignments to the same integer in the same context will yield the exact same result, we can see that the arguement to LOAD_CONST is 0 for both a and b:

>>> import dis
>>> dis.dis("a = 1000 ; b = 1000")     
  1           0 LOAD_CONST               0 (1000)
              3 STORE_NAME               0 (a)
              6 LOAD_CONST               0 (1000)
              9 STORE_NAME               1 (b)
             12 LOAD_CONST               1 (None)
             15 RETURN_VALUE
                                       # ^ this is the argument 

where as in an interactive session each command is compiled separately (so that they can be executed separately) so the constants will be different:

>>> code1 = compile("a = 1000","<dummy file>","exec")
>>> code2 = compile("a = 1000","<dummy file>","exec")
>>> code1.co_consts, code2.co_consts
((1000, None), (1000, None))
>>> code1.co_consts[0] is code2.co_consts[0]
False

Similarly the constant in a function will always be the same but it will be different to the constant in other functions:

def f():
    return 1000
def g():
    return 1000 #different code object!!

#these all work
assert f() is f()
assert g() is g()
assert f() is not g()
assert f() is not 1000 and g() is not 1000

Also note that as @AniMenon has pointed out the numbers from -5 to 256 are singletons for optimization so the same will not hold true for numbers in that range.

这篇关于Python:使用 PyCharm 和 IDLE/python 时的不同结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆