Tutorial¶
Function overloading¶
PyExt function overloading is simple:
@overload.argc(1)
def x(a): print 'Function 1 called'
@overload.argc(2)
def x(a, b): print 'Function 2 called'
x(1)
x(1, 2)
Easy, no? Now, if we wanted to overload by types also, we could do this:
@overload.args(int)
def x(a): print 'Function 1 called'
@overload.args(str)
def x(a): print 'Function 2 called'
x(1)
x('s')
If you’re in Python 3, you can also use function annotations by passing None
as the parameter:
@overload.args(None)
def x(a:int): print 'Function 1 called'
@overload.args(None)
def x(a:str): print 'Function 2 called'
x(1)
x('s')
If you are overloading a class method, you need to pass is_cls
as True
:
class x(object):
@overload.args(str, is_cls=True)
def f(self, s): print 'Got string'
@overload.args(int, is_cls=True)
def f(self, i): print 'Got int'
obj = x()
x.f('s')
x.f(2)
Runtime Modules¶
Runtime modules let you create a full module object at runtime. Here’s an example:
mymodule = RuntimeModule.from_objects('module_name', 'module_docstring', a=1, b=2)
import mymodule # Module object is added to sys.path
print mymodule.a, mymodule.b
We can also create our module object from a string:
mystr = '''
a = 1
b = 2
def do_nothing(x): return 'Nothing'
'''
RuntimeModule.from_string('module_name', 'module_docstring', mystr)
import mymodule
print mymodule.a, mymodule.b, mymodule.do_nothing(1)
Switch statement¶
Switch statements are just as easy as everything else:
with switch(3):
if case(1): print 'Huh?'
if case(2): print 'What the...'
if case(3): print "That's better!"
if case.default(): print 'Ummm...'
This is equilavent to the following C code:
switch(3)
{
case 1:
puts("Huh?"); break;
case 2:
puts("What the..."); break;
case 3:
puts("That's better!"); break;
default:
puts("Ummm...")
}
The equivalent of break
is case.quit()
. There is an implicit quit at the end of every case. If you want the C-style fallthrough, pass cstyle=True
to the call to switch
.
For chaining case
statements, pass multiple arguments to case. For example, this C:
switch(myvar)
{
case 1:
case 3:
case 5:
case 7:
case 9:
puts("An odd number"); break;
case 2:
case 4:
case 6:
case 8:
puts("An even number"); break;
default:
puts("The number is either greater that 9 or less than 1");
}
is equilavent to this Python code using PyExt:
with switch(myvar):
if case(1,3,5,7,9): print 'An odd number'
if case(2,4,6,8): print 'An even number'
if case.default(): print 'The number is either greater that 9 or less than 1'
Tail recursion removal¶
Have you ever had a function that went way over the recursion limit? PyExt has a feature that eliminates that problem:
@tail_recurse()
def add(a, b):
if a == 0: return b
return add(a-1, b+1)
add(1000000, 1) # Doesn't max the recursion limit!
Function annotations¶
PyExt lets you use Python 3’s function annotations...on Python 2! Here is an example:
@fannotate('ret', a='a', b=1,)
def x(a, b):
return 0
This is equilavent to:
def x(a:'a', b:1) -> 'ret':
return 0
Safe unpacking¶
Say you have a string whose value is 'a:b'
. Now, say you want to split this string at the colon. You’ll probably do this:
a, b = my_string.split(':')
But what if my_string
doesn’t have a colon? You’ll have to do this:
a, b = my_string.split(':') if ':' in my_string else (my_string, None)
Python 3 lets you simply do this:
a, *b = my_string.split(':')
Also, with string partitioning, you can do this:
a, _, b = my_string.partition(':')
But say you’re not working on a string. Say you’re using a tuple:
a, b = my_tuple
If my_tuple isn’t big enough or is too big, it’ll throw an error. As stated above, Python 3 fixes this. But what if you’re using Python 2? PyExt comes with a nifty function called safe_unpack
that lets you do this:
a, b = safe_unpack(my_tuple, 2)
The first parameter is the sequence to unpack, while the second is the expected length. If the sequence is too large, the excess values are ignored. If it’s too small, None
is substituted in for the extra values.
You can also specify a value other than None
to fill in the extra spaces:
a, b = safe_unpack(my_tuple, 2, fill='')
Expression assignment¶
Languages such as C and C++ allow you to use an assignment as an expression. For people who don’t know what that means, here’s an example, in C:
if (my_var = my_func())
This is equilavent to the following Python code:
my_var = my_func()
if my_var:
PyExt lets you do it the easy way:
if assign('my_var', my_func()):
Swap if condition¶
Code like this is more than often encountered:
if my_variable == some_value:
my_variable = some_other_value
Using PyExt, that code gets shortened to:
compare_and_swap('my_variable', some_value, some_other_value)