0

I have a class that wants to be initialized from a few possible inputs. However a combination of no function overloading and my relative inexperience with the language makes me unsure of how to proceed. Any advice?

alexgolec
  • 26,898
  • 33
  • 107
  • 159

4 Answers4

4

Check out this question asked earlier.

In short, the recommendation is that you use classmethods or isinstance(), with classmethods being heavily favored.

Community
  • 1
  • 1
Zeke
  • 1,974
  • 18
  • 33
  • 1
    Thomas Wouter's accepted answer on that link is really good (and much better than a blind suggestion to use duck-typing) but as it stands, I think that your answer should have been a comment. Maybe you should add some more info, for example, mentioning the use of class methods for this sort of thing. – aaronasterling Nov 17 '10 at 04:56
  • @aaronasterling: Thanks, I'm still picking up what proper SO etiquette is in these cases. – Zeke Nov 17 '10 at 05:03
3

With Python, you should use duck typing. Wikipedia has a good section on its use in Python at http://en.wikipedia.org/wiki/Duck_typing#In_Python

Chris Morgan
  • 86,207
  • 24
  • 208
  • 215
2

Contrary to what others have answered, it's not rare to check for types in __init__. For example the array.array class in the Python Standard library accepts an optional initializer argument, which may be a list, string, or iterable. The documentation explicitly states different actions take place based on the type. For another example of the same treatment by argument type see decimal.Decimal. Or see zipfile.Zipfile, which accepts a file argument "where file can be either a path to a file (a string) or a file-like object." (Here we see both explicit type checking (a string) and duck typing (a file-like object) all in one!)

If you find explicit type checking in __init__ is getting messy, try a different approach. Use factory functions instead. For example, let's say you have a triangle module with a Triangle class. There are many ways to construct a triangle. Rather than having __init__ handle all these ways, you could add factory methods to your module:

  • triangle.from_sas(side1, angle, side2)
  • triangle.from_asa(angle1, side, angle2)
  • triangle.from_sss(side1, side2, side3)
  • triangle.from_aas(angle1, angle2, side)

These factory methods could also be rolled into the Triangle class, using the @classmethod decorator. For an excellent example of this technique see Thomas Wouter's fine answer to stackoverflow question overloading init in python.

Community
  • 1
  • 1
Steven Rumbalski
  • 44,786
  • 9
  • 89
  • 119
1

No, don't check for types explicitly. Python is a duck typed language. If the wrong type is passed, a TypeError will be raised. That's it. You need not bother about the type, that is the responsibility of the programmer.

user225312
  • 126,773
  • 69
  • 172
  • 181