python:can语句是否在表达式内?

时间:2017-02-13 12:24:44

标签: python

我试图实现一个懒惰的属性。比如,一个对象由object._x = None初始化,然后我想写一些东西

@property
def x(self):
    return self._x or (init_x_value(); x)

以便仅在第一次查找属性时调用初始化程序。

在scala中,表达式可以包含语句。 python中有类似的东西可能。如果没有,是否有任何替代方法来实现它,或者我应该坚持使用if-else

3 个答案:

答案 0 :(得分:6)

如果init_x_value 返回None ,您只需使用:

return self._x or init_x_value() or self._x

但是请注意,就像@3Doubloons在评论中所说,如果self._x false-ish ,例如None[](空列表),()一个空元组,或者已经覆盖__bool__方法的类,它将转移到计算成本昂贵的init方法。

如果init_x_value 返回计算出的x 值本身,您甚至可以将其写为:

return self._x or init_x_value()

这是因为Python中的or比较特殊:x or y的作用如下:

if bool(x):
    return x
else:
    return y

并且懒惰地生成xy。由于bool(None)在第一种情况下为False,因此会检查self._x。如果self._xNone,则会通过调用init_x_value()来继续,因为该方法不会返回隐式返回None的任何内容,or不接受该方法 - 链也是,所以它最终解析为现在设置的最后一个self._x

答案 1 :(得分:5)

回答标题问题本身:不,在Python中,表达式不能包含语句。周期。

编写getter的正确pythonic方法是:

@property
def x(self):
    # assume _x defaults to None 
    if self._x is None:
        # here you can have has many statements as 
        # you like ;)
        self._x = init_x_value()
    return self._x

可能看起来不像三重奏那么聪明,或者'或内联语句或其他任何内容,但它可以是简单,直接,清晰和可读

答案 2 :(得分:1)

您可以隐藏函数中的语句:

@property
def x(self):
    def initialize_and_return_x():
        init_x_value()
        return self._x
    return self._x or initialize_and_return_x()