Python private variables in a class I was reading about private variables and functions in Python and I managed to get almost everything except one thing.

Is it recommended to write underscore before variables defined inside a function?

Here is the code so it can be more clear:

Version 1:

class House():

    def __init__(self):

        self.color = "RED"
        self._discount_coefficient = 0.8

    def get_total_charges(self, json_from_communal_company):

        _water_price        = json_from_communal_company["waterPrice"]
        _electricity_price  = json_from_communal_company["electricityPrice"]

        _total_charges = self._discount_coefficient * (_water_price + _electricity_price)

        return _total_charges


Version 2:

class House():

    def __init__(self):

        self.color = "RED"
        self._discount_coefficient = 0.8

    def get_total_charges(self, json_from_communal_company):

        water_price        = json_from_communal_company["waterPrice"]
        electricity_price  = json_from_communal_company["electricityPrice"]

        total_charges = self._discount_coefficient * (water_price + electricity_price)

        return total_charges


I know that variable _discount_coefficient needs to have underscore, but I am not sure if variables water_price, electricity_price and total_charges should have underscore or not.

Can someone tell me which version is better and why?
For Python object names, a single leading underscore denotes private status, like you said.
Unlike other languages, this is not enforced however.
It is only a (strong) suggestion for users of your code not to use these objects.

This could be internal variables, like your self._discount_coefficient.
For example, maybe you implement a @property that secrectly stores something in self._discount_coefficient, but for the calling code, you need to enforce an invariant (in this case, maybe 0 &lt;= self._discount_coefficient &lt;= 1).
This way, users can only set the discount_coefficient instance attribute (notice no underscore) to be within 0 and 1, otherwise an error is thrown.
Nothing keeps people from directly mingling with self._discount_coefficient, however.
Therefore, the convention of underscores; basically a contract where all guarantees you make about your code are void if private objects are modified directly.

Having said all that (which you probably heard of already), it becomes clear that users of your House class can never directly access the variables inside your method anyway.
They either access get_total_charges as a whole, or nothing.
The decision is therefore to either hide get_total_charges as a whole, if it is private, or leave it like in your case.

water_price, electricity_price and total_charges are only temporary variables and tossed the moment the function returns.
They are never relevant to the entire private/public debate because they are never seen from calling code.
If you assigned any of them as instance attributes via self, you would have to decide for or against a leading underscore.

As it is, Version 2 looks fine.
As for remaining style, House() can just be House and the equal signs before json_from_communal_company should not be aligned (looks fine now but is a maintenance nightmare).