def isBig(x):
if x > 4:
return 'apple'
else:
return 'orange'
这有效:
if isBig(y): return isBig(y)
这不起作用:
if fruit = isBig(y): return fruit
为什么第二个不起作用!?我想要一个 1 班轮。除了,第一个将调用函数 TWICE。
如何使其成为 1 班轮,而无需两次调用该函数?
def isBig(x):
if x > 4:
return 'apple'
else:
return 'orange'
这有效:
if isBig(y): return isBig(y)
这不起作用:
if fruit = isBig(y): return fruit
为什么第二个不起作用!?我想要一个 1 班轮。除了,第一个将调用函数 TWICE。
如何使其成为 1 班轮,而无需两次调用该函数?
开始Python 3.8
,并引入赋值表达式 (PEP 572) ( :=
operator),现在可以将条件值 ( isBig(y)
) 作为变量 ( x
) 捕获,以便在条件体中重用它:
if x := isBig(y): return x
我看到其他人已经指出了我的旧“分配和设置”食谱食谱,它最简单的版本归结为:
class Holder(object):
def set(self, value):
self.value = value
return value
def get(self):
return self.value
h = Holder()
...
if h.set(isBig(y)): return h.get()
但是,这主要是为了简化 Python 和在if
or中直接支持赋值的语言之间的音译while
。如果您在级联中有“数百个”这样的检查和返回,那么做一些完全不同的事情会更好:
hundreds = isBig, isSmall, isJuicy, isBlah, ...
for predicate in hundreds:
result = predicate(y)
if result: return result
甚至像
return next(x for x in (f(y) for f in hundreds) if x)
如果没有满足谓词,则可以得到 StopIteration 异常,或者
return next((x for x in (f(y) for f in hundreds) if x)), None)
ifNone
是不满足谓词时的正确返回值等。
几乎总是,使用(甚至希望使用;-)Holder
技巧/非习语是一种“设计气味”,它建议寻找一种不同的、更 Pythonic 的方法——Holder
有理由的一种情况正是我的特殊情况设计它,即您希望在 Python 代码和一些非 Python 代码之间保持密切对应的情况(您正在用 Python 音译参考算法并希望它在将其重构为更 Python 的形式之前首先工作,或者您'将 Python 重新编写为原型,一旦它有效工作,它将被音译为 C++、C#、Java 等)。
一个衬里不起作用,因为在 Python 中,赋值 ( fruit = isBig(y)
) 是一个语句,而不是一个表达式。在 C、C++、Perl 和无数其他语言中,它是一个表达式,你可以把它放在 anif
或 awhile
或任何你喜欢的地方,但在 Python 中不行,因为 Python 的创建者认为这太容易被误用(或滥用) 来编写“聪明”的代码(就像你正在尝试的那样)。
另外,您的示例相当愚蠢。isBig()
将始终评估为true
,因为唯一为假的字符串是空字符串 ( ""
),因此if
在这种情况下您的语句是无用的。我认为这只是对您尝试做的事情的简化。只需这样做:
tmp = isBig(y)
if tmp: return tmp
真的有那么糟糕吗?
如果您想用 PHP(或 C)编写代码,请在其中编写代码。不要试图将它的方法强加到另一种语言上。
Python 背后的基本原则之一(在我看来)是它的可读性。你应该使用:
fruit = isBig(y)
if fruit: return fruit
我还要提一下,你的使用isXXX()
很奇怪;它通常用于返回布尔值。特别是在这种情况下,您在IF
语句中使用它。
您可以使用生成器:
def ensure(x):
if x: yield x
for fruit in ensure(isBig(y)):
return fruit
问题是赋值操作不能被评估为具有布尔值。该if
语句依赖于能够评估布尔值。例如,
>>> fruit = 'apple'
>>> bool(fruit = 'apple')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/Users/jem/<ipython console> in <module>()
TypeError: 'fruit' is an invalid keyword argument for this function
>>> bool('a')
True
print "apple" if x > 4 else "orange"