开发者

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

开发者 https://www.devze.com 2023-02-24 02:05 出处:网络
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 nev

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

精彩评论

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

关注公众号