4

I've come across answers here for type checking in general, type checking for numbers, and type checking for strings. Most people seem to respond by saying that type checking should never be performed in python (< 2.6) due to duck typing. My (limited) understanding of duck typing is that type is determined by use of an object's attributes. What do I do if I'm not using any attributes?

I have a simple function that determines constants based on the argument, which should be a number. I raise an exception defined by

class outOfBoundsError(ValueError):
    """
    Specified value is outside the domain.
    """

with a message telling them the number they gave me is too big. I would like to keep this message specific. But if the argument is a string (like 'charlie'), it still considers the argument to be greater than my specified number (and raises my exception). Should I just add a dummy line to the code like argument + 2 so that a TypeError is raised?

Note: I don't know anything about ABCs but I don't think they're available to me since the latest python version we have access to is 2.5 : (.

Community
  • 1
  • 1
aeroNotAuto
  • 260
  • 3
  • 13
  • 5
    Anyone who tells you that you should *never* do something is wrong. If you were *never* supposed to do that, then there wouldn't be convenient helper methods like `isinstance`. You *usually* don't want to do that, and novices often fall back on it based on habits from other languages, but you should seriously question anyone who says *never*. – Glenn Maynard Apr 11 '11 at 20:02
  • "Rules exist to make you *think* before breaking them." – Ben Blank Apr 11 '11 at 20:27

4 Answers4

6

A common duck-typish Python solution to this problem is to (try to) convert what you got to what you need. For example, if you need an integer:

def getconstants(arg):
    try:
        arg = int(arg)
    except:
        raise TypeError("expected integer, or something that can be converted to one, but got " + repr(arg))

The int type constructor knows how to deal with many built-in types. Additionally, types that are convertible to an int type can implement the __int__() special method, which would allow them to be used here. If the user passed in a string, that would work fine too as long as it contained only digits.

Your idea of performing some operation that could only be performed on a numeric type (such as adding 2) is similar, and would work great in many cases, but would fail with strings that can be converted to the desired type, so I like the type conversion better.

You could probably get by without the try/except here, since int() will raise either TypeError or ValueError if it can't do the conversion, but I think TypeError is more appropriate since you are mainly interested in the object's type, so I chose to catch the exception and always raise TypeError.

kindall
  • 178,883
  • 35
  • 278
  • 309
2

My honest answer to

Most people seem to respond by saying that type checking should never be performed in python (< 2.6) due to duck typing

is: nonsense.

Type-checking - were needed - is common practice.

Don't listen to all and everything and don't accept every statement unfiltered.

1

You can check to make sure you're expecting a type you support initially. i.e.

def foo(arg):
    if not isinstance(arg, int):
        raise TypeError
    ...

Nothing wrong with that if you're only supporting integers.

yan
  • 20,644
  • 3
  • 38
  • 48
0

Introspection works for this...primitive types have class names too:

>>> i=2
>>> i.__class__.__name__
'int'
>>> s="two"
>>> s.__class__.__name__
'str'
>>>
AJ.
  • 27,586
  • 18
  • 84
  • 94