Python: could there be an expression inside the expression?

I am trying to implement a lazy property. Let's say the object is initialized object._x = None , and then I want to write something

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

so that the initializer is called only when the attribute is first viewed.

In scala, an expression may contain statements. Something like this is possible in python. If not, is there an alternative way to implement it, or should I stick with if-else ?

+5
source share
3 answers

If init_x_value returns None , you can simply use:

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

Note that, for example, @ 3Doubloons says in its comment that if self._x is something false, like None , [] (empty list), () an empty tuple or a class that overrides the __bool__ method, it will go over to the init method, which can be computationally expensive.

In case init_x_value returns the computed value of x , you can even write it like this:

 return self._x or init_x_value() 

This is because or in Python is pretty special: x or y works like:

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

and x and y generated lazily. Since bool(None) is False in the first case, it thus checks self._x . If self._x is None , it will be called by calling init_x_value() , since this method does not return anything that it implicitly returns None , which is not accepted by the or chain, so it finally resolves to the last self._x , which is now set.

+6
source

To answer the heading itself: no, in Python, an expression cannot contain an operator. period.

The correct pythonic way to record your recipient:

 @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 

It may not seem as smart as a triple 'or' or inline statement or something else, but it's simple, simple, clear and understandable.

+5
source

You can hide the statements in the function:

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

Source: https://habr.com/ru/post/1264161/


All Articles