Gael Lorieul
Gael Lorieul

Reputation: 3246

Should I always test the types of each function's parameters?

I have a function which has a parameter intTup. That function is being called by a user and hence the input might be erroneous, so I want to validate it.

In particular, intTup must :

So, as soon as the function is executed, those properties are checked :

def myFunc(intTup)
    if type(intTup) is not tuple:
        print("intTup       = ", intTup)
        print("type(intTup) = ", type(intTup))
        raise Exception('In parameter intTup : should be a tuple of float')
    elif (len(h) != 3) :
        print("intTup      = ", intTup)
        print("len(intTup) = ", len(intTup))
        raise Exception('In parameter intTup : should contain three atoms')
    elif [int]*len(intTup) == map(type,intTup):
        print("intTup       = ", intTup)
        print("type(intTup) = ", map(type,intTup))
        raise Exception('In parameter h : all atoms should be ints')
    # Some actual code follow these tests

Of course that type of checks is frequently encountered : anytime a function admits a parameter of type tuple containing n values of type t a similar check must be run. Hence, should I define a function checkTuple(tupleToTest, shouldBeLen, shouldBeType) to automate these checks ? Or should I leave how it is ? How do you proceed in your scripts ?

Upvotes: 0

Views: 76

Answers (5)

Reblochon Masque
Reblochon Masque

Reputation: 36662

If you really (really?) must break ducktyping, you could assert the validity of the params as follows:

def myFunc(intTup):
    """intTup is a tuple of size 3"""
    assert(isinstance(intTup, tuple)), "not a tuple"
    assert(len(intTup) == 3), "not length 3"

Easier to Ask Forgiveness than Permission :)

You could take a look at the warnings module.

Upvotes: 1

Cong Ma
Cong Ma

Reputation: 11302

No. In Python you use "duck type": if something walks like a duck, quacks like a duck, and swims like a duck, it is identified with a duck.

In other words, with Python, we believe that it is what you do that defines what you are.

Which means you should rely on the property of an object, rather than its type. In your case, you just use the input the way a "3-tuple containing ints" is meant to be used, and handle exceptions.

See also: isinstance considered harmful.

Upvotes: 4

DorElias
DorElias

Reputation: 2313

You can make a decorator to check if

     def validate(func):
         def f(*args, **kwargs): 
             if args[0] is not tuple or len(args[0])! =3:
                 raise Exception("invalid parameter") 
             return func(*args, **kwargs) 
         return f

Upvotes: 0

John
John

Reputation: 5287

Perhaps you should consider EAFP.

Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.

docs

Try to process user input and if it fails for whatever reason, raise an exception. This is not how would you normally do it in most of other languages where emphasis is on prevention of error, but for python it is common to use EAFP principle.

In other words, do not validate.

Upvotes: 2

Emil Vikström
Emil Vikström

Reputation: 91912

What's the point of using a language without static type checking if you are going to implement runtime type checking anyway? The answer to your question is that: no; you should not always check the parameter constraints. If you want to have that kind of control there are better tools for the job. There are cases where you may want to type check, such as when accepting input from users or outside processes, but you do not want to always do it.

Upvotes: 1

Related Questions