Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python: can statement be inside expression?

Tags:

python

I'm trying to implement a lazy property. Say, an object is initialize by 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 the first time the attribute is looked up.

In scala, an expression can contain statements. Is something similar possible in python. If not, is there any alternative way to implement it, or should I stick with if-else?

like image 592
blue_note Avatar asked Feb 13 '17 12:02

blue_note


People also ask

Can an expression contain a statement?

@NirajRaut As an example, in the assignment statement a = 42 the right-hand side 42 is an expression, but it's not an expression statement. Any expression could be used as a statement, but not every expression is actually used as a statement.

Is a statement an expression in Python?

In short – An Expression always evaluates to a value. And, A statement does something, like creating a variable or displaying a value, it only does whatever the statement says.

What is difference between expression and statement in Python?

An expression can be defined as any element in our utility that evaluates some values. An expression evaluates a value. A declaration does something. Statements represent a motion or command e.g print statements, mission statements.

What is difference between expression and statement?

In programming language terminology, an “expression” is a combination of values and functions that are combined and interpreted by the compiler to create a new value, as opposed to a “statement” which is just a standalone unit of execution and doesn't return anything.


3 Answers

If init_x_value returns None, you can simply use:

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

Note however, like @3Doubloons says in their comment, that if self._x is something false-ish like None, [] (an empty list), () an empty tuple, or a class which has overridden the __bool__ method, it will move on to the init method wich can be computationally expensive.

In case init_x_value returns the calculated x value itself, you can even write it like:

return self._x or init_x_value()

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

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

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

like image 97
Willem Van Onsem Avatar answered Oct 06 '22 01:10

Willem Van Onsem


To answer the title question itself : no, in Python an expression can not contain a statement. period.

The proper pythonic way to write your getter is:

@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

might not look as smart as triple 'or' or inline statements or whatever but it's as simple, straightforward, clear and readable as it can be.

like image 27
bruno desthuilliers Avatar answered Oct 06 '22 00:10

bruno desthuilliers


You can hide the statements in a function:

@property
def x(self):
    def initialize_and_return_x():
        init_x_value()
        return self._x
    return self._x or initialize_and_return_x()
like image 25
Siphor Avatar answered Oct 06 '22 00:10

Siphor