Search code examples
pythonpython-3.5

Should a class convert types of the parameters at init time? If so, how?


I've defined a class with 5 instance variables

class PassPredictData:
    def __init__(self, rating, name, lat, long, elev):
        self.rating = rating
        # rest of init code

I want to ensure:

  • rating is an int
  • name is a str
  • lat, long, elev are floats

When reading my input file, everything works creating a list of objects based on my class. When I start comparing values I got weird results since the instance variables were still strings.

Is the "most Pythonic way" to cast the values as the object is being created using int(string) and float(string) when calling the constructor or should this casting be done with logic inside the class?


Solution

  • If you type import this in the Python interpreter, you will get "The Zen of Python, by Tim Peters". The first three lines seem to apply to your situation:

    Beautiful is better than ugly.
    Explicit is better than implicit.
    Simple is better than complex.
    

    I would recommend implementing your class like this:

    class PassPredictData:
        def __init__(self, rating, name, lat, long, elev):
            self.rating = int(rating)
            self.name = str(name)
            self.lat = float(lat)
            self.long = float(long)
            self.elev = float(elev)
    

    This is the implementation you mention in your question. It is simple and explicit. Beauty is in the eye of the beholder.

    Responses to Comments

    The implementation is explicit to the writer of the class versus some other solution that hides the type conversion behind some opaque mechanism.

    There is a valid argument that it is not obvious from the function signature what the expected parameter types are. However, the question implies that all parameters are passed as strings. In that case, the expected type is str for all the constructor parameters. Perhaps the question title does not clearly describe the problem. Maybe a better title would be "Enforce Instance Variable Types When Passing Strings as Parameters to Constructor".

    Note

    I encourage folks to look at the revision history of the question to see the whole story.