Should the attributes of a class be part of the public interface even when they could break its methods?

by pob   Last Updated July 11, 2019 19:05 PM

As a minimal example, consider the following (in Python):

class Foo:
    def __init__(self, bar):
        # Assume bar is a valid at this point
        self.bar = bar

    def divide_by_bar(self, num):
        return num / self.bar

If the attribute bar is public, my understanding is that it is valid for the client to do something like:

>>> foo = Foo(1)
>>> foo.bar = 0
>>> foo.divide_by_bar(2)
Traceback (most recent call last):
   ...
ZeroDivisionError: division by zero

We encountered a more complex version of this in our team and I suggested to make the attribute private, or read-only (or to consider the handling the exception). However, I got the reply that, since it is only used in one place in our code base, it is fine to leave it like that. I agreed to that, but I have noticed numerous examples of this practice in our code base and I am uncertain when should one be more strict with these cases. Should I ignore it until it is used in multiple places?



Answers 1


Python has no good language-level encapsulation mechanisms, so in a way this doesn't matter. But Python linters do recognize the “leading underscores mean private” convention, so respecting this encapsulation can be enforced.

Here, just adding an underscore will make the intention of the code much clearer. You shouldn't necessarily go and seek out any such code snippets to fix them, but if you do come across such an example, then improving it would be a no-brainer.

Alternatively, Python offers some mechanisms to make objects read-only. I like the attrs module for easily creating immutable classes, and with Python 3.7 you could also use dataclasses. Other approaches are probably not worth the effort, e.g. namedtuples have weird syntax and do stuff that you might not want (like making objects comparable).

Although the code could be improved (by clearly marking private fields as private, or by making the object immutable), this kind of Python code is not uncommon. If you want a safe programming language then Python is not for you. A lot of stuff in Python is merely a convention, and everyone should respect that convention. What is part of the public interface is not necessarily defined by a naming convention or by some real encapsulation mechanism, but often by what is mentioned in the documentation.

amon
amon
July 11, 2019 18:48 PM

Related Questions


Defensive Programming - "Return" placement

Updated June 03, 2015 23:02 PM


Working on code written by novice developers

Updated February 28, 2017 16:05 PM

Is creativity important for software developers?

Updated September 18, 2018 23:05 PM