挑战你,Python 益智题:如何让这个函数返回 True
嗨,大家好!我正在浏览 /r/python 并遇到了 这篇文章:
有这样一个函数:
def check(x):
if x+1 is 1+x:
return False
if x+2 is not 2+x:
return False
return True
提供一个输入,使得 1 加上它,还是和它是同个对象的实例,但是 2 加上它不再是同个对象的实例。
解决方案1:自定义类
我个人认为解决此挑战的方式是:
def check(x):
if x+1 is 1+x:
return False
if x+2 is not 2+x:
return False
return True
class Test(int):
def __add__(self, v):
if v == 1:
return 0
else:
return v
print(check(Test()))
# output: True
让我解释一下它是如何工作的。在 Python 中,当我们使用 +
运算符时,Python 会根据对象在运算符的哪一侧来调用不同的特殊方法。如果对象在运算符的左侧,则将调用 __ add __
;如果在右侧,则将调用 __ radd __
。
如果调用了 Test() + 1
则返回 0
,如果调用 1 + Test()
则返回 1
。诀窍在于,我们只重载其中一种特殊方法,而另一种不变。这将帮我们通过第一个 if 条件。如果再看一遍,您会发现它也帮助我们通过了第二次的 if 检查,因为如果输入不是 1 的话,直接返回输入,所以 Test() + 2
永远等价于 2 + Test()
。
但是,在看了评论之后,我发现了另一个不需要自定义类的解决方案。
解决方案2:唯一的整数
用户 /u/SethGecko11 提出了出奇简单的答案:
def check(x):
if x+1 is 1+x:
return False
if x+2 is not 2+x:
return False
return True
print(check(-7))
# output: True
只有 -7 可行。任何一个其他的数字都不会返回 True。如果您对为什么这样做感到困惑,那么您并不孤单。我必须阅读评论以找出原因。
很显然,在 Python 中,整数 -5 到 256 是预分配的。当您执行任何操作且结果在该范围内时,您将获得预分配的对象。这些都是单例,因此 is
运算符将返回 True
。如果您尝试使用不属于此范围的整数,则会得到一个新实例。
预分配这些整数的内存要求不是很高,但是显然性能提升是巨大的。
因此,当您使用 -7 作为输入时,将得到一个新的 -6 实例,但当答案为 -5 时将获得相同的实例。正是由于 if 语句的构造方式,所以这对上限 (256) 无效。如果检查功能是这样实现的,则 255 可以作为答案:
def check(x):
if x+1 is not 1+x:
return False
if x+2 is 2+x:
return False
return True
希望您在本文中学到了新东西。我认为您永远都不会在任何代码库中使用此功能,但是它是一个非常好的脑筋急转弯,甚至可以使经验丰富的 Python 开发人员措手不及。
编程愉快!
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。