开发者

How can I avoid type checking a python object if its attributes aren't used?

I've come across answers here for type checking in general, typ开发者_如何学Goe 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 : (.


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.


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.


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.


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

>>> i=2
>>> i.__class__.__name__
'int'
>>> s="two"
>>> s.__class__.__name__
'str'
>>>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜