11

If I have python function with a string argument which needs to be in a specific list of values, what's the best way to handle this? Is there a convention to expressing this in the docstrings or anything?

eg.

def makeShape(shape):
   assert shape in ["circle", "square", "triangle"]

Is there a nicer way to express that shape should always be one of those three values?

ninhenzo64
  • 687
  • 1
  • 8
  • 22
  • If this function is part of a class, perhaps making that list a sort of class constant... Other than that, looks good to me. – Lix Mar 15 '14 at 00:37
  • Can you please clarify why you are using a string and what are your fundamental constraints? Could the enum idea suggested by @blue-ice be what you really need? – jrennie Mar 15 '14 at 00:58
  • Ok - maybe my example is a bit misleading as in that case you could create a class for each shape. My problem (this time - it seems to come up a lot though) is that I have an interface which runs in three modes: Load, Save and View. I want to pass a "mode" arg, but it can only be one of those three values. The Enum solution is very nice, but I'm on python2.6 unfortunately (in maya and nuke). – ninhenzo64 Mar 15 '14 at 18:25
  • @ninhenzo64 As noted in a comment on my answer, `enum`s have been backported to 2.6 through pypi. It should be do-able for you. – Blue Ice Mar 16 '14 at 00:31

2 Answers2

12

You could use an enum for the correct sort of shapes:

class rightShape(Enum):
    circle = 1
    square = 2
    triangle = 3

def makeShape(rightShape):
    # code in function

This will throw an honest-to-goodness error if you try to pass the function anything but a circle, square, or triangle.

Blue Ice
  • 7,654
  • 5
  • 31
  • 50
  • Since the latest Ubuntu only has 3.3, I think it's worth noting that Enum's are new in python 3.4. – jrennie Mar 15 '14 at 00:56
  • 2
    @jrennie However, it has been backported from 3.4 to earlier versions- see [this question](http://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python). – Blue Ice Mar 15 '14 at 00:58
  • 1
    This does not raise an error though? It just accepts anything because of Pythons duck-typing? Isn't this answer simply wrong? – Thomas Apr 19 '22 at 07:59
  • This does not seem to be working in python3 – Mithun Kinarullathil Jun 01 '22 at 16:15
2

If this is a genuine error, you should raise an exception. I think TypeError would be a reasonable choice, but you may want to define your own.

assert statements are for development. Note that they are ignored when the -O argument is used, so they should not be relied upon to catch errors.

jrennie
  • 1,857
  • 12
  • 16