[我看到其他人已经指出了我的旧“分配并设置”食谱手册,其最简单的版本归结为:
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
或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)
如果None
是不满足谓词时正确的返回值,等等。>几乎总是使用(或什至希望;-)Holder
技巧/非惯用语是一种“设计气味”,它暗示着寻找一种不同且更具Python风格的方法-在这种情况下,Holder
是合理的正是我为其设计的特例,例如,您要保持Python代码与某些非Python之间的紧密对应关系(您要在Python中音译参考算法,并希望它先工作然后再重构为一种更Python化的形式,或者您正在将Python编写为原型,一旦其有效运行,它将被音译为C ++,C#,Java等)。
一个衬里不起作用,因为在Python中,赋值(
fruit = isBig(y)
)是语句,而不是表达式。在C,C ++,Perl和许多其他语言中,它是一个表达式,您可以将其放在
if
或
while
或任何您喜欢的语言中,但不能放在Python中,因为Python的创建者认为这是太容易被滥用(或滥用)以编写“聪明的”代码(就像您要尝试的那样)。
而且,您的示例相当愚蠢。 isBig()
将始终取值为true
,因为唯一为假的字符串是空字符串(""
),因此,在这种情况下,if
语句无用。我认为这只是您要尝试做的事情的简化。只需这样做:
tmp = isBig(y)
if tmp: return tmp
真的更糟吗?
如果要使用PHP(或C)进行编码,请在其中进行编码。不要试图将其方法强制使用另一种语言。
在我看来,Python背后的基本原则之一是它的可读性。您应该使用:
fruit = isBig(y)
if fruit: return fruit
我还应该提到您对isXXX()
的使用很奇怪;它通常用于返回布尔值。特别是在这种情况下,您需要在IF
语句中使用它。
问题是赋值操作不能被评估为具有布尔值。
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
您可以使用生成器:
def ensure(x):
if x: yield x
for fruit in ensure(isBig(y)):
return fruit
print "apple" if x > 4 else "orange"