Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 240
lucholland Avatar asked Aug 09 '17 15:08

lucholland


People also ask

What is the purpose of __ init __?

The __init__ method lets the class initialize the object's attributes and serves no other purpose. It is only used within classes.

Does a class need an init method?

No, it is not necessary but it helps in so many ways. people from Java or OOPS background understand better. For every class instance, there is an object chaining that needs to complete when we instantiate any class by creating an object. If we don't put it compiler/interpreter puts it.

What does the __ init __ method do in a class definition?

__init__ method It is called as a constructor in object oriented terminology. This method is called when an object is created from a class and it allows the class to initialize the attributes of the class.

What parameters are required to be passed to a class constructor?

This method has four parameters: the loan amount, the interest rate, the future value and the number of periods. The first three are double-precision floating point numbers, and the fourth is an integer.


2 Answers

Personally, I would do any string parsing before passing the values to the constructor, unless parsing is one (or the) explicitly stated responsibility of the class. I prefer my program to fail because I didn't explicitly cast a value than to be too flexible and end up in a Javascript-like 0 == "0" situation. That said, if you want to accept strings as parameters you can just call int(my_parameter) or float(my_parameter) as needed in the constructor and that will make sure this are numbers not matter you pass a number, a string or even a Boolean.

In case you want to know more about type safety in Python, you can take a look at type annotations, which are supported by type checkers like mypy, and the traits package for type safety in class attributes.

like image 132
jdehesa Avatar answered Sep 24 '22 03:09

jdehesa


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.

like image 37
David Cullen Avatar answered Sep 24 '22 03:09

David Cullen