我正在尝试实现一个惰性属性。比如说,一个对象被object._x = None
初始化,然后我想写点什么
@property
def x(self):
return self._x or (init_x_value(); x)
以便仅在首次查找属性时调用初始值设定项。
在 scala 中,表达式可以包含语句。在 python 中是否有类似的可能性。如果没有,是否有其他方法来实现它,或者我应该坚持if-else
?
如果init_x_value
返回None
,您可以简单地使用:
return self._x or init_x_value() or self._x
但是请注意,就像@3Doubloons在他们的评论中所说的那样,如果self._x
是错误的东西,例如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
是懒惰生成的。由于在第一种情况下False
bool(None)
,因此它将检查self._x
。如果self._x
None
,它将通过调用init_x_value()
继续进行,因为该方法不会返回它隐式返回的任何内容None
or
链也不接受,因此它最终解析到现在设置的最后一个self._x
。
要回答标题问题本身:不,在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
可能看起来不像三重"或"或内联语句或其他任何东西那么聪明,但它尽可能简单、直接、清晰和可读。
您可以在函数中隐藏语句:
@property
def x(self):
def initialize_and_return_x():
init_x_value()
return self._x
return self._x or initialize_and_return_x()