Pythonic的条件变量初始化方式是什么?

13

由于 Python 的作用域规则,一旦在作用域内初始化了变量,之后就可以使用该变量。由于条件语句不会引入新的作用域,因此其他语言中的结构(如在条件语句之前初始化变量)并非必需。例如,我们可能会写出以下代码:

def foo(optionalvar = None):
    # some processing, resulting in...
    message = get_message()
    if optionalvar is not None:
        # some other processing, resulting in...
        message = get_other_message()
    # ... rest of function that uses message

或者,我们也可以选择:

def foo(optionalvar = None):
    if optionalvar is None:
        # processing, resulting in...
        message = get_message()
    else:
        # other processing, resulting in...
        message = get_other_message()
    # ... rest of function that uses message

当然,get_messageget_other_message函数可能有很多行代码,而且基本上与问题无关(可以假设每个路径后程序的状态相同);这里的目标是使message在此函数段之外也能够使用。

我在其他问题中也看到过类似的结构,例如:

哪种结构更可接受?


1
这完全取决于您是否希望get_message有条件地运行还是无条件地运行,不是吗? - user395760
这里的重点不是要调用函数,而是构建“message”的方式:函数本身并不重要。 - Robert P
1
无论是函数还是其他,一个语义上的区别就是其中一个无条件地运行了一半的代码。如果这有所不同,争论风格也没有多大意义。 - user395760
同意。这就是为什么我想知道第二个结构在Python中是否被认为是良好的风格! :)(我认为它是...我想看看别人的想法。) - Robert P
1
是的,第二个函数是完全可接受的,这也是我可能会使用的。+1 delnan。 - Michael Hoffman
显示剩余3条评论
5个回答

13

Python还有一种非常有用的if语法模式,你可以在这里使用

  message = get_other_message() if optional_var else get_message()

或者如果你想要严格比较是否为 None

  message = get_other_message() if optional_var is not None else get_message()
与您发布的示例1)不同,此代码不会不必要地调用get_message()。

1
这是 Python 的官方条件赋值方式(自版本2.5起),至少就语言本身而言是这样。请查看 PEP 308 获取更多信息。 - voithos
看起来PEP 308建议第二种格式是以前可接受的做法。好知道! - Robert P

4

一般来说,第二种方法更好且更通用,因为它不会无条件调用get_message。如果该函数不需要资源激励,则可以使用,但考虑到搜索功能。

def search(engine):
    results = get_from_google()
    if engine == 'bing':
       results = get_from_bing()

显然这不是好的做法,我无法想象出第二种情况会有如此糟糕的场景,因此一个遍历所有选项并最终执行默认选项的方法是最好的,例如:
def search(engine):
    if engine == 'bing':
       results = get_from_bing()
    else:
       results = get_from_google()

1

我认为更符合Python风格的做法是不要设置关于这个的明确规则,而是坚持小型函数更好的理念(部分原因是因为可以在引入新名称时轻松记住)。

不过,如果您的条件测试比if/else复杂得多,您可能会冒着所有测试失败并稍后使用未定义名称的风险,从而导致可能的运行时错误,除非您非常小心。当可能时,这可能是第一种风格的论据。


0

答案取决于是否需要 get_message() 的副作用。

在大多数情况下,第二种方法显然更好,因为不会执行产生不想要结果的代码。但是如果您需要副作用,则应选择第一种版本。


0

最好(即:更安全)在条件之外初始化您的变量。如果您必须定义其他条件甚至删除一些条件,则稍后使用message的用户可能会出现未初始化的变量异常。


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