Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.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中的返回操作数?_Python_Boolean_Operands - Fatal编程技术网

为什么';和'&';或';Python中的返回操作数?

为什么';和'&';或';Python中的返回操作数?,python,boolean,operands,Python,Boolean,Operands,我正在通过LPTHW,我遇到了一些我无法理解的事情。什么时候您希望布尔值和或或返回布尔值以外的值?LPTHW文本声明,所有像python这样的语言都有这种行为。他指的是解释型语言还是编译型语言,还是鸭子型语言还是静态型语言 我运行了以下代码: >>> False and 1 False >>> True and 1 1 >>> 1 and False False >>> 1 and True True >>>

我正在通过LPTHW,我遇到了一些我无法理解的事情。什么时候您希望布尔值
返回布尔值以外的值?LPTHW文本声明,所有像python这样的语言都有这种行为。他指的是解释型语言还是编译型语言,还是鸭子型语言还是静态型语言

我运行了以下代码:

>>> False and 1
False
>>> True and 1
1
>>> 1 and False
False
>>> 1 and True
True
>>> True and 121
121
>>> False or 1
1
>>> False or 112
112
>>> False or "Khadijah"
'Khadijah'
>>> True and 'Khadijah'
'Khadijah'
>>> False or 'b'
'b'
>>> b = (1, 2, "K")
>>> b
(1, 2, 'K')
>>> False or b
(1, 2, 'K')
>>> 
请帮我理解这里发生了什么

根据文件:

除非另有说明,否则具有布尔结果的操作和内置函数始终返回
0
False
表示False,返回
1
True
表示True。(重要例外:布尔运算
始终返回其操作数之一。)

根据LPTHW: 为什么
“test”和“test”
返回“test”或
1和1
返回1而不是True?
Python和许多类似的语言将其中一个操作数返回到它们的布尔表达式,而不仅仅是True或False。这意味着如果执行False和1,则得到第一个操作数(False),如果执行True和1,则得到第二个操作数(1)。玩一下这个。

我想你对医生说的话有些困惑。请看以下两个文档部分:。引用第一节最后一段:

除非另有说明,否则具有布尔结果的操作和内置函数始终返回
0
False
表示False,返回
1
True
表示True。(重要例外:布尔运算
始终返回其操作数之一。)

正如您所看到的,您对操作和内置函数的看法是正确的,但请参见重要的异常部分,很好地说明了布尔运算符将返回其操作数之一

现在,它们能返回什么几乎不取决于操作员的短路逻辑。对于
运算符,它将返回表达式中的第一个truthy值,因为当它找到一个truthy值时,整个表达式为true。如果每个操作数都是假操作数,
将返回最后一个操作数,这意味着它对每个操作数进行迭代,无法找到真操作数

对于
运算符,如果表达式为真,则返回最后一个操作数;如果表达式为假,则返回第一个假操作数。你可以阅读更多关于

你的问题中有很多例子,让我们分析其中一些:

>>> False and 1  # return false (short circuited at first falsey value)
False
>>> True and 1   # return 1 (never short circuited and return the last truthy value)
1
>>> 1 and False  # return false (short circuited at first falsey value, in this case the last operand)
False
>>> 1 and True  # return True (never short circuited and return the last truthy value)
True
>>> True and 121  # return 121 (never short circuited and return the last truthy value)
121
>>> False or 1  # return 1 (since the first operand was falsey, or kept looking for a first truthy value which happened to be the last operator)
1
>>> False or 112  # return 112 for same reason as above
112
>>> False or "Khadijah"  # return "Khadijah" for same reason as above
'Khadijah'
>>> True and 'Khadijah'  # return "Khadijah" because same reason as second example
'Khadijah'
我认为这应该说明一点。为了帮助您进一步理解为什么这是有用的,请考虑下面的例子:

您有一个随机生成名称的函数

import random

def generate_name():
    return random.choice(['John', 'Carl', 'Tiffany'])
您有一个变量,您不知道它是否已经分配了一个名称,因此不需要执行以下操作:

if var is None:
    var = generate_name()
您可以使用oneliner:

var = var or generate_name()
由于
None
是一个假值,
将继续搜索并计算第二个操作数,即调用函数,最终返回生成的名称。这是一个非常愚蠢的例子,我看到了这种风格的更好的用法(虽然不是在Python中)。我现在想不出更好的例子了。你也可以看看这些问题,在这个主题上有非常有用的答案:

最后但并非最不重要的一点是,这与静态类型、duck类型、动态、解释、编译等语言无关。这只是一种语言特性,可能很方便,而且非常常见,因为我能想到的几乎每种编程语言都提供了这种特性


希望这有帮助

人们希望
求值为操作数(而不是总是求值为
),以便支持以下习惯用法:

def foo(self):
    # currentfoo might be None, in which case return the default
    return self.currentfoo or self.defaultfoo()

def foobar(self):
    # foo() might return None, in which case return None
    foo = self.foo()
    return foo and foo.bar()
你当然可以质疑这些习语的价值,尤其是如果你不习惯它们的话。如果使用显式的
if
,则始终可以编写等效代码


作为对他们不利的一点,他们对虚假价值的全部范围是否可能并有意加以解释,或者仅仅是评论中提到的一个(其他虚假价值是不允许的)留下了一些疑问。但是,对于使用值的真实性的代码来说,这通常是正确的,该值可能不是
true
False
。它偶尔但很少导致误解。

这与Python中实现短路效应的方式有关

使用
(记住
True和X=X
),将正确表达式的结果推送到堆栈中,如果结果为false,则立即将其弹出,否则将弹出第二个表达式:

>>> import dis
>>> 
>>> dis.dis(lambda : True and 0)
  1           0 LOAD_CONST               2 (True)
              3 JUMP_IF_FALSE_OR_POP     9
              6 LOAD_CONST               1 (0)
        >>    9 RETURN_VALUE
>>>
>>> True and 0
0
>>> 0 and True
0
>>>
微笑者:

def exec_and(obj1, obj2):
    if bool(obj1) != False:
        return obj2
    return obj1
def exec_or(obj1, obj2):
    if bool(obj1) != True:
        return obj2
    return obj1
使用
,如果第一个表达式为true,则会立即弹出该表达式。如果不是,则第二个表达式被弹出,现在结果实际上取决于第二个表达式

>>> dis.dis(lambda : 0 or False)
  1           0 LOAD_CONST               1 (0)
              3 JUMP_IF_TRUE_OR_POP      9
              6 LOAD_CONST               2 (False)
        >>    9 RETURN_VALUE
>>>
>>> True or 0
True
>>> 1 or False
1
>>> False or 1
1
>>>
微笑者:

def exec_and(obj1, obj2):
    if bool(obj1) != False:
        return obj2
    return obj1
def exec_or(obj1, obj2):
    if bool(obj1) != True:
        return obj2
    return obj1

考虑以下用例:

element = dict.has_key('foo') and dict['foo']
元素
设置为
dict['foo']
(如果存在),否则
False
。这在编写函数返回值或失败时返回
False
时非常有用

使用

print element or 'Not found!'
将这两行放在一起将打印出
dict['foo']
,如果它存在,否则将打印出
“找不到!”
(我使用
str()
,否则当
元素
0
(或
False
)时
会失败,因为这被认为是错误的,因为我们只打印它并不重要)

这可以简化为

print dict.has_key('foo') and str(dict['foo']) or 'Not found!'
在功能上等同于:

if dict.has_key('foo'):
    print dict['foo']
else:
    print 'Not found!'

布尔运算也是惰性的<当发现第一个假操作数时,code>和
操作将停止计算操作数<当找到第一个真操作数时,code>或
操作将停止计算操作数。如果