我试图实现一个懒惰的属性。比如,一个对象由object._x = None
初始化,然后我想写一些东西
@property
def x(self):
return self._x or (init_x_value(); x)
以便仅在第一次查找属性时调用初始化程序。
在scala中,表达式可以包含语句。 python中有类似的东西可能。如果没有,是否有任何替代方法来实现它,或者我应该坚持使用if-else
?
答案 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
并且懒惰地生成x
和y
。由于bool(None)
在第一种情况下为False
,因此会检查self._x
。如果self._x
为None
,则会通过调用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()