Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中为True定义值时的奇怪行为_Python_Boolean_Boolean Expression - Fatal编程技术网

在Python中为True定义值时的奇怪行为

在Python中为True定义值时的奇怪行为,python,boolean,boolean-expression,Python,Boolean,Boolean Expression,这不是一个实际问题——我只是对我观察到的一些奇怪的行为感到好奇,并想知道我是否正确理解“is”操作符 下面是一些可预测的Python解释器输出: >>> True is True True >>> (1==1) is True True 现在让我们定义一个名为True的变量: >>> True = 'abc' >>> True == 'abc' True >>> True is 'abc' True 对

这不是一个实际问题——我只是对我观察到的一些奇怪的行为感到好奇,并想知道我是否正确理解“is”操作符

下面是一些可预测的Python解释器输出:

>>> True is True
True
>>> (1==1) is True
True
现在让我们定义一个名为True的变量:

>>> True = 'abc'
>>> True == 'abc'
True
>>> True is 'abc'
True
对于布尔运算,解释器仍将返回“True”,但布尔运算的结果被认为既不等于“abc”,也不等于True

>>> (1==1)
True
>>> (1==1) is 'abc'
False
>>> (1==1) is True
False

有人能解释这种奇怪的行为吗?

正如在这里经常发生的那样,我想我在打字的时候找到了答案


有两个“True”:一个是布尔值,另一个是名为True的变量;一开始,他们是平等的。这就是为什么像(1==1)这样的布尔运算即使在名为True的变量被更改时仍然可以返回True——它们返回的是布尔值True。但是它们并不等于“True”变量的新值,这是一个字符串。

正在发生的是名称空间和交互式控制台隐藏它

最初,您有正常的
True
,它是
\uuuuuuu内置的模块的一部分

当您重新定义
True
时,实际上是在当前模块中定义它,在这种情况下,该模块只是默认的
\uuuuuuu main\uuuuu

因此,实际上有两个不同的对象<代码>\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

In [1]: import __builtin__, __main__

In [2]: True = "a bad idea"

In [3]: __main__.True
Out[3]: 'a bad idea'

In [4]: __builtin__.True
Out[4]: True

要在您自己的答案中添加更多内容(应该是注释,但长度较长,需要格式化):

id
中的值(本质上)是Python中对象的内部标识,如果愿意,也可以称为“真实名称”。(从字面上看,它是一个C指针,变成了一个整数。)
测试比较对象标识

>>> 1==1
True
>>> id(1==1)
7744528
这表明比较的布尔结果是“旧的”
True
,该结果仍然可用作
\uuuuu内置的.True

In [1]: import __builtin__, __main__

In [2]: True = "a bad idea"

In [3]: __main__.True
Out[3]: 'a bad idea'

In [4]: __builtin__.True
Out[4]: True
您重新绑定了名称
\uuuuu main\uuuu.True
(解释器
>>
提示符处的当前模块为
\uuuuuuu main\uuuuu
):

以及:

当初学者编写类似以下函数时,Python程序中也经常发生这种情况:

def foo(list):
    ...
list
是一个内置函数,但在函数
foo
中,名称已重新绑定到参数。然后在
部分的某个地方,他们得到了一个惊喜:

    x = list(y)
他们希望这个函数调用
\uuuuu内置的.list
,但它尝试将其局部变量作为函数调用


(有可能,但通常不是很好的风格,
导入并通过这些名称调用东西。也有可能重新绑定
内置名称,但这是一个更糟糕的想法。:-)

我喜欢这种情况@JMK是的,我想,伊玛是第一个回答这个问题的人:P我没有看到他的答案。
True
基本上是
1
,带有一种奇特的
repr()
:-)True不是带有花哨的
repr()
1
。它是一个单例内置值,在条件中恰好计算为1。就解释器而言,使用不同的单例值也有这种行为,比如
if省略号:print 3
,除了明显的模糊性使其在风格上异常之外,没有什么错。从
省略号
示例中可以看出(省略号在numpy数组中也有一个没有人使用的不同的切片函数),不能将单例的值看作是
1
。例如,比较
True+1
省略号+1
isinstance(True,int)
奇怪的是
True
不是保留关键字(或Python拥有的任何关键字)。@iamnotmaynard:
True
已成为Python 3中的关键字,而且赋值将引发
SyntaxError:assignment to keyword
。。。您可以将值重新分配给几乎所有的值。谢天谢地,它们通常是本地的,所以当一个粗心的程序员在他们的函数中这样做时,它会保持本地化状态。@CorleyBrigman:例如,
id
是一个内置函数,但它经常被重新指定为对象属性(例如在Django ORM中)。我不确定它是否“不小心”,因为
id()
builtin对于调试以外的任何事情都没有多大用处。作为对象属性,它是可以的-这不是C,您将始终以
self.id
object.id
(在命名空间中)的身份访问它。虽然我见过(甚至写过)像UID列表中id的
这样的代码:
等等,但这很容易做到,这就解释了如何隐藏它。。。但是,如果您愿意,也可以执行
\uuuuuu内置\uuuuu.True=4
。所以这并不能完全回答最初的问题。@CorleyBrigman:我在解释最初问题中代码中发生了什么。我只是说它比这个更深。。。您可以执行
\uuuu内置
,并且
1==1
仍将返回True。甚至在内置代码下面的东西都指向真实的对象,或者它是在python核心中处理的。
def foo(list):
    ...
    x = list(y)