在Python中设置回退值的最佳方法是什么?

3

我最近经常使用以下模式:

x = 3
if this:
   this.process()
   if this.something:
       x = this.a_value

我不想做这个:

if this and (this.process() or True) and this.someting:
    x = this.a_value
else:
    x = 3

或者这样:
if this:
   this.process()
   if this.something:
       x = this.a_value
   else:
       x = 3
else:
    x = 3

但我不禁觉得,先设定一个值然后再去改变它有些混乱,尤其是在某些情况下很少使用备用值的时候。

是否有更好/更整洁的方法?


这个是否总是具有属性a_value? - ChipJust
5个回答

3
我认为在你提供的三个选项中,第一个选项即你正在使用的选项是最好的。代码清晰易懂,每个人都会知道发生了什么。我想不到有更简洁/整洁的方法,这也是我会根据“简单比复杂好”的原则编写代码的方式。
关于“我不禁觉得设置值然后再更改它有点混乱”,如果你想要一个默认值,那就没有绕过设置默认值的方法。
这确实比使用其他两种else方法要整洁得多。可读性很重要。

1
最简单的不需要更改值的方法是这样的:
processed = False
if this:
   this.process()
   if this.something:
       x = this.a_value
       processed = True
if not processed:
    x = 3

但是这样你就引入了另一个变量。如果你的默认值很容易计算,我会在顶部将x设置为3。人们会理解那是默认值。如果默认值计算起来很耗时,那么我会添加额外的布尔选项。


1
从代码维护的角度来看,我会接受第一或第二种情况,但由于重复,不会接受第三种情况。
PS:在Python中,我通常希望看到使用self来引用类实例对象,而不是this。最好不要使用this来引用类实例对象或其他任何目的,以避免混淆。

好的,我正在考虑类似于“这个,那个,另一个”之类的虚假变量名称。 - Jake
(this.process() or True) 让我对第二个选项失去兴趣。它看起来很愚蠢且不清晰。 - Jake
@Jake:实际上,我没有仔细看第二个选项的逻辑表达式。是的,我同意,那很不清楚,所以我更喜欢第一个选项。 - Craig McQueen

0

我会让this.proccess()返回this并执行

 try: x = this.avalue if this.process() and this.something else 3
 except AttributeError: x = 3;

尽管裸露的异常处理并不总是很好(取决于流程的复杂性)

[编辑]第二个例子行不通,所以我把它删掉了


您不需要一个裸露的except。这怎么解决了this.something测试的问题? - Marcin
修复了 ;) 谢谢...哦,我没有考虑到那个,你是对的...该死,让我想想...好的,我认为已经修复了...不确定还没有测试过。 - Joran Beasley
我仍然认为原始代码(第一选项)更清晰易懂/易于理解和遵循(编辑/更新:基于“简单胜于复杂”的原则 :))。 - Levon
是的,我认为这更容易理解...但这也不错,也许更符合“Pythonic”(编辑)_基于EAFP设计原则_。 - Joran Beasley

0

这将避免首先设置默认值,而不重复:

def noncefunc(default):
    if this:
       this.process()
       if this.something: return this.a_value 
    return default

x = noncefunc(3)

虽然这并不是特别清晰,当然也不是比你现有的更先进。如果你想做这种事情,最好使用一种天生支持函数式风格的语言。如果 Python 是那种语言就好了,但可惜它不是。

或者:

class breakexception(exception):pass
try:
   if this:
       this.process()
       if this.something: 
          x = this.a_value
          raise breakexception()
except breakexception: pass
else: x = 3

再次强调,只有在非默认设置未首先设置时,此操作才会设置默认值,但这并不容易理解。

最后:

if this:
    this.process()
    if this.something: 
       x = this.a_value
try: x = x
except UnboundLocalError: x = 3

这可能是你所拥有的替代方案中最清晰的一个,但它并没有比你原来的形式更具进步性。
坚持你现在的选择。

感谢您提交了一些替代想法! - Jake

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接