【发布时间】:2017-12-26 22:00:59
【问题描述】:
问题
我有这样的代码
if condition:
a = f(x)
else:
a = g(y)
块内部a 的初始化对我来说看起来很糟糕。能不能写得更好?
我不能使用三元运算符,因为函数名和/或参数列表很长。 说“长”是指下面的表达方式
a = f(x) if condition else g(y)
将采用超过 79 个(有时甚至超过 119 个)实名符号,而不是 a、f、g、x、y 和 condition。
使用多个斜线会使代码变得丑陋和混乱。
我不想用默认函数之一的结果初始化a,因为这两个函数都很慢,我不能允许这样的开销
a = g(y)
if condition:
a = f(x)
我可以用None 初始化变量,但是这个解决方案够漂亮吗?
a = None
if condition:
a = f(x)
else:
a = g(y)
让我解释一下我的立场:在块内的 C 和 C++ 变量中,块作为它们的作用域。在 ES6 中引入了 let 关键字——它允许创建具有与 C 和 C++ 中的变量相同的作用域规则的变量。使用旧的 var 关键字定义的变量具有与 Python 中相似的范围规则。
这就是为什么我认为如果我想在这些块之外使用变量,应该在这些块之外进行变量的初始化。
更新
这里是更复杂的例子
for obj in gen:
# do something with the `obj`
if predicate(obj):
try:
result = f(obj)
except Exception as e:
log(e)
continue
else:
result = g(obj)
# do something useful with the `result`
else:
result = h(obj)
display(result)
我检查了一些生成器gen 的元素,处理它们并在每次迭代时对result 执行一些操作。
然后我想对循环外的最后一个result 做点什么。
不预先为result 分配一个虚拟值是否足够pythonic?
这不会降低代码的可读性吗?
问题
在if/else/for/etc里面初始化变量好不好?在 Python 中?
【问题讨论】:
-
将内联 if-else 包裹在括号中,然后您可以在没有斜杠的情况下换行,并添加前导空格以提高可读性
-
Python 没有块作用域。您的
a = None在语义上等同于将其省略... -
我倾向于使用外部 a = None。原因是,随着您的逻辑变得更加有条件和复杂,您可能会遇到分支未分配 a 的 NameError ,这会抛出您。设置 a 后,您可以针对 None 执行 getattr(a, 'somevar','default') 。在您的 简单 示例中,可能不值得。
-
@JLPeyret 是的,你明白我的意思:我说的是一般情况,但可能是因为术语错误,我被理解错了
-
@f5r5e5d 多行三元运算符根本不会比普通的
if-else更具可读性