5

Consider this example of a function (and its use) that receives one parameter which is only meaningful as int:

def fun(index): index = int(index) # do something with index def main(): print fun(1e6) 

I find that I keep repeating this pattern on several functions that deal with integers since it ensures that I really receive some integer number (note that 1e6 is a floating point instance).

This is a bit cumbersome and if forgotten once it could produce problems (there is code that reacts differently to floating-point/integer/string/... values). So could this be somehow encoded in the function signature?

E.g. something along the lines of this pseudo-code:

def fun(int index): # do something with index 
4
  • This is a bit of a non-answer (as I have never actually worked with them) but there are some frame works (zope is one I think) that will do this for you Commented Apr 7, 2013 at 3:10
  • Type enforcement isn't very Pythonic. Is there any reason that you are avoiding the duck-typing paradigm? Commented Apr 7, 2013 at 4:03
  • @JoelCornett: The rounding errors (stemming from the exponent notation of floating point numbers) cause problems when comparing to 0 and I had some loops overshoot. (But I'm right in the middle of learning Python, coming from C++ and Haskell --- so I'm not surprised that I have trouble accepting duck-typing.) Commented Apr 7, 2013 at 4:19
  • If you are going to use index for a loop, use it as range(index). That will raise an exception if you feed it an object that cannot be represented as an integer. Commented Apr 7, 2013 at 8:58

2 Answers 2

9

First of all, you shouldn't really be doing this (even though some days I kind of want to as well…). Python is not statically-typed, so you shouldn't really be introducing cludgy static-typing.

Buuut, to answer you question. Decorators:

def ensure_int(fn): def wrapper(num): return fn(int(num)) return wrapper def test(num): return num + 2 @ensure_int def test2(num): return num + 2 

Works like:

> test("2") ERROR!!! >test2("2") 4 
Sign up to request clarification or add additional context in comments.

6 Comments

this will behave badly with 1e65 as an arguement
Thanks for pointing it out! There are edge-cases to handle, but I'll leave that as an exercise to the user. (hint, convert to int then str) ;)
Hmmm, I would have to implement a decorator for each function signature (you usually have additional parameters that don't necessarily have that restriction), which is really more cumbersome than useful. I was more thinking about a specification that is close to the individual formal parameters.
+1 "Python is not statically-typed". If you don't know what you're passing to a function, does it matter what the return is?
@bitmask If you're using Python 3, you could do something with function annotation, as BrenBarn described. Really, you should've be doing this in any sort of ad hoc manner (i.e. unless you're writing a Type System for Python, which would be more academic than practical). You should be writing functions which compose neatly, not type-casting all over the place (very un-Pythonic).
|
2

In Python 3 you could use function annotations and then write a decorator that converts (or tries to convert) arguments to the types you specify.

In Python 2 you can't do this in the way you seem to want. Python 2's syntax doesn't support putting anything in the function definition except the arguments themselves, and you can't alter Python's syntax to let you put types in there as well.

2 Comments

Some sample code would be really helpful!
hey @ToJo I shared sample code for you :) stackoverflow.com/questions/15299878/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.