I am attempting to write a program to perform arithmetic mod n, given n. I was wondering if there is any way within Python (preferably 2.7) to dynamically define a function such that its behavior depends on the name used to call it. More concretely, I would like to define a function named "*mod", where * is an integer, that then does arithmetic mod *. Perhaps more clearly, I would like to write one function definition for *mod that defines the functions 2mod, 3mod, 4mod, and so on. Is this possible? I apologize if a similar question has already been asked or if my answer is readily available in documentation; I tried to search for it, but I didn't know exactly how to describe the functionality that I'm looking for, so I may have missed it.
Thanks!
You don't want to do that. Just make a simple function and pass both numbers as arguments:
def mod(x, n):
return x % n
print mod(5, 2)
# 1
Well, if you really, really want to, look at this quick hack. It uses a wrapper class to wrap the module in a class, so you can use __getattr__:
import sys
import functools
def add(a, b):
return a + b
def sub(a, b):
return a - b
class Wrapper(object):
def __init__(self, wrapped):
self.wrapped = wrapped
def __getattr__(self, name):
try:
# quick hack. Don't try this at home :-)
f = ''.join(x for x in name if not x.isdigit())
n = ''.join(x for x in name if x.isdigit())
return functools.partial(getattr(self.wrapped, f), int(n))
except:
return getattr(self.wrapped, name)
sys.modules[__name__] = Wrapper(sys.modules[__name__])
Now, when you call e.g. add10(12) on this module, the result is 22. Note that method names must not start with a number, but you could use names like _add and call the methods like _55add(45) and so on.
But I would follow Haidro advice: You don't want to do that. Just calling the method with two arguments is a lot simpler.
Using globals, lambda:
for i in range(2, 5):
globals()['mod{}'.format(i)] = lambda x, n=i: x % n
assert mod2(4) == 0
assert mod2(3) == 1
assert mod3(2) == 2
assert mod3(1) == 1
assert mod4(1) == 1
assert mod4(2) == 2
assert mod4(3) == 3
assert mod4(9) == 1
You could achieve this by generating the functions as a string, and then exec this string to get the function in the current namespace. Something like:
n = 2
s = 'def mod%i(x):' % n
s += ' return x %% %i' % n
exec s
This would define the function mod2(x)
Related
I recently started coding in Python and I was wondering if it's possible to return a function that specializes another function.
For example, in Haskell you can create a function that adds 5 to any given number like this:
sumFive = (+5)
Is it somehow possible in Python?
I think the other answers are misunderstanding the question. I believe the OP is asking about partial application of a function, in his example the function is (+).
If the goal isn't partial application, the solution is as simple as:
def sumFive(x): return x + 5
For partial application in Python, we can use this function: https://docs.python.org/2/library/functools.html#functools.partial
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
newkeywords.update(fkeywords)
return func(*(args + fargs), **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
Then, we must turn the + operator into a function (I don't believe there's a lightweight syntax to do so like in Haskell):
def plus(x, y): return x + y
Finally:
sumFive = partial(plus, 5)
Not nearly as nice as in Haskell, but it works:
>>> sumFive(7)
12
Python's design does not naturally support the evaluation of a multi-variable function into a sequence of single-variable functions (currying). As other answers point out, the related (but distinct) concept of partial application is more straightforward to do using partial from the functools module.
However, the PyMonad library supplies you with the tools to make currying possible in Python, providing a "collection of classes for programming with functors, applicative functors and monads."
Use the curry decorator to decorate a function that accepts any number of arguments:
from pymonad import curry
#curry
def add(x, y):
return x + y
It is then very easy to curry add. The syntax is not too dissimilar to Haskell's:
>>> add5 = add(5)
>>> add5(12)
17
Note that here the add and add5 functions are instances of PyMonad's Reader monad class, not a normal Python function object:
>>> add
<pymonad.Reader.Reader at 0x7f7024ccf908>
This allows, for example, the possibility of using simpler syntax to compose functions (easy to do in Haskell, normally much less so in Python).
Finally, it's worth noting that the infix operator + is not a Python function: + calls into the left-hand operand's __add__ method, or the right-hand operand's __radd__ method and returns the result. You'll need to decorate these class methods for the objects you're working with if you want to curry using + (disclaimer: I've not tried to do this yet).
Yup. Python supports lambda expressions:
sumFive = lambda x: x + 5
for i in range(5):
print sumFive(i),
#OUTPUT 5,6,7,8,9
Python functions can return functions, allowing you to create higher-order functions. For example, here is a higher-order function which can specialize a function of two variables:
def specialize(f,a,i):
def g(x):
if i == 0:
return f(a,x)
else:
return f(x,a)
return g
Used like this:
>>> def subtract(x,y): return x - y
>>> f = specialize(subtract,5,0)
>>> g = specialize(subtract,5,1)
>>> f(7)
-2
>>> g(7)
2
But -- there is really no need to reinvent the wheel, the module functools has a number of useful higher-order functions that any Haskell programmer would find useful, including partial for partial function application, which is what you are asking about.
As it was pointed out, python does have lambda functions, so the following does solve the problem:
# Haskell: sumFive = (+5)
sumFive = lambda x : x + 5
I think this is more useful with the fact that python has first class functions (1,2)
def summation(n, term):
total, k = 0, 1
while k <= n:
total, k = total + term(k), k + 1
return total
def identity(x):
return x
def sum_naturals(n):
return summation(n, identity)
sum_naturals(10) # Returns 55
# Now for something a bit more complex
def pi_term(x):
return 8 / ((4*x-3) * (4*x-1))
def pi_sum(n):
return summation(n, pi_term)
pi_sum(1e6) # returns: 3.141592153589902
You can find more on functional programming and python here
For the most generic Haskell style currying, look at partial from the functools module.
I am trying to create a set of functions in python that will all do a similar operation on a set of inputs. All of the functions have one input parameter fixed and half of them also need a second parameter. For the sake of simplicity, below is a toy example with only two functions.
Now, I want, in my script, to run the appropriate function, depending on what the user input as a number. Here, the user is the random function (so the minimum example works). What I want to do is something like this:
def function_1(*args):
return args[0]
def function_2(*args):
return args[0] * args[1]
x = 10
y = 20
i = random.randint(1,2)
f = function_1 if i==1 else function_2
return_value = f(x,y)
And it works, but it seems messy to me. I would rather have function_1 defined as
def function_1(x):
return x
Another way would be to define
def function_1(x,y):
return x
But that leaves me with a dangling y parameter.
but that will not work as easily. Is my way the "proper" way of solving my problem or does there exist a better way?
There are couple of approaches here, all of them adding more boiler-plate code.
There is also this PEP which may be interesting to you.
But 'pythonic' way of doing it is not as elegant as usual function overloading due to the fact that functions are just class attributes.
So you can either go with function like that:
def foo(*args):
and then count how many args you've got which will be very broad but very flexible as well.
another approach is the default arguments:
def foo(first, second=None, third=None)
less flexible but easier to predict, and then lastly you can also use:
def foo(anything)
and detect the type of anything in your function acting accordingly.
Your monkey-patching example can work too, but it becomes more complex if you use it with class methods, and does make introspection tricky.
EDIT: Also, for your case you may want to keep the functions separate and write single 'dispatcher' function that will call appropriate function for you depending on the arguments, which is probably best solution considering above.
EDIT2: base on your comments I believe that following approach may work for you
def weigh_dispatcher(*args, **kwargs):
#decide which function to call base on args
if 'somethingspecial' in kwargs:
return weight2(*args, **kwargs)
def weight_prep(arg):
#common part here
def weight1(arg1, arg2):
weitht_prep(arg1)
#rest of the func
def weight2(arg1, arg2, arg3):
weitht_prep(arg1)
#rest of the func
alternatively you can move the common part into the dispatcher
You may also have a function with optional second argument:
def function_1(x, y = None):
if y != None:
return x + y
else:
return x
Here's the sample run:
>>> function_1(3)
3
>>> function_1(3, 4)
7
Or even optional multiple arguments! Check this out:
def function_2(x, *args):
return x + sum(args)
And the sample run:
>>> function_2(3)
3
>>> function_2(3, 4)
7
>>> function_2(3, 4, 5, 6, 7)
25
You may here refer to args as to list:
def function_3(x, *args):
if len(args) < 1:
return x
else:
return x + sum(args)
And the sample run:
>>> function_3(1,2,3,4,5)
15
I want a function to refer to itself. e.g. to be recursive.
So I do something like that:
def fib(n):
return n if n <= 1 else fib(n-1)+fib(n-2)
This is fine most of the time, but fib does not, actually, refer to itself; it refers to the the binding of fib in the enclosing block. So if for some reason fib is reassigned, it will break:
>>> foo = fib
>>> fib = foo(10)
>>> x = foo(8)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in fib
TypeError: 'int' object is not callable
How can I prevent this from happening (from inside fib), if at all possible? As far as I know, the name of fib does not exist before the function-definition is fully executed; Are there any workarounds?
I don't have a real use case where it may actually happen; I am asking out of sheer curiosity.
I'd make a decorator for this
from functools import wraps
def selfcaller(func):
#wraps(func)
def wrapper(*args, **kwargs):
return func(wrapper, *args, **kwargs)
return wrapper
And use it like
#selfcaller
def fib(self, n):
return n if n <= 1 else self(n-1)+self(n-2)
This is actually a readable way to define a Fixed Point Combinator (or Y Combinator):
fix = lambda g: (lambda f: g(lambda arg: f(f)(arg))) (lambda f: g(lambda arg: f(f)(arg)))
usage:
fib = fix(lambda self: lambda n: n if n <= 1 else self(n-1)+self(n-2))
or:
#fix
def fib(self):
return lambda n: n if n <= 1 else self(n-1)+self(n-2)
The binding here happens in the formal parameter, so the problem does not arise.
There's no way to do what you're trying to do. You're right that fib does not exist before the function definition is executed (or, worse, it exists but refers to something completely different…), which means there is no workaround from inside fib that can possibly work.*
However, if you're willing to drop that requirement, there are workarounds that do work. For example:
def _fibmaker():
def fib(n):
return n if n <= 1 else fib(n-1)+fib(n-2)
return fib
fib = _fibmaker()
del _fibmaker
Now fib is referring to the binding in the closure from the local environment of a call to _fibmaker. Of course even that can be replaced if you really want to, but it's not easy (the fib.__closure__ attribute is not writable; it's a tuple, so you can't replace any of its cells; each cell's cell_contents is a readonly attribute, …), and there's no way you're going to do it by accident.
There are other ways to do this (e.g., use a special placeholder inside fib, and a decorator that replaces the placeholder with the decorated function), and they're all about equally unobvious and ugly, which may seem to violate TOOWTDI. But in this case, the "it" is something you probably don't want to do, so it doesn't really matter.
Here's one way you can write a general, pure-python decorator for a function that uses self instead of its own name, without needing an extra self parameter to the function:
def selfcaller(func):
env = {}
newfunc = types.FunctionType(func.__code__, globals=env)
env['self'] = newfunc
return newfunc
#selfcaller
def fib(n):
return n if n <= 1 else self(n-1)+self(n-2)
Of course this won't work on a function that has any free variables that are bound from globals, but you can fix that with a bit of introspection. And, while we're at it, we can also remove the need to use self inside the function's definition:
def selfcaller(func):
env = dict(func.__globals__)
newfunc = types.FunctionType(func.__code__, globals=env)
env[func.__code__.co_name] = newfunc
return newfunc
This is Python 3.x-specific; some of the attribute names are different in 2.x, but otherwise it's the same.
This still isn't 100% fully general. For example, if you want to be able to use it on methods so they can still call themselves even if the class or object redefines their name, you need slightly different tricks. And there are some pathological cases that might require building a new CodeType out of func.__code__.co_code. But the basic idea is the same.
* As far as Python is concerned, until the name is bound, it doesn't exist… but obviously, under the covers, the interpreter has to know the name of the function you're defining. And at least some interpreters offer non-portable ways to get at that information.
For example, in CPython 3.x, you can very easily get the name of the function currently being defined—it's just sys._getframe().f_code.co_name.
Of course this won't directly do you any good, because nothing (or the wrong thing) is bound to that name. But notice that f_code in there. That's the current frame's code object. Of course you can't call a code object directly, but you can do so indirectly, either by generating a new function out of it, or by using bytecodehacks.
For example:
def fib2(n):
f = sys._getframe()
fib2 = types.FunctionType(f.f_code, globals=globals())
return n if n<=1 else fib2(n-1)+fib2(n-2)
Again, this won't handle every pathological case… but the only way I can think of to do so is to actually keep a circular reference to the frame, or at least its globals (e.g., by passing globals=f.f_globals), which seems like a very bad idea.
See Frame Hacks for more clever things you can do.
Finally, if you're willing to step out of Python entirely, you can create an import hook that preprocesses or compiles your code from a Python custom-extended with, say, defrec into pure Python and/or bytecode.
And if you're thinking "But that sounds like it would be a lot nicer as a macro than as a preprocessor hack, if only Python had macros"… then you'll probably prefer to use a preprocessor hack that gives Python macros, like MacroPy, and then write your extensions as macros.
Like abamert said "..there is no way around the problem from inside ..".
Here's my approach:
def fib(n):
def fib(n):
return n if n <= 1 else fib(n-1)+fib(n-2)
return fib(n)
Someone asked me for a macro based solution for this, so here it is:
# macropy/my_macro.py
from macropy.core.macros import *
macros = Macros()
#macros.decorator()
def recursive(tree, **kw):
tree.decorator_list = []
wrapper = FunctionDef(
name=tree.name,
args=tree.args,
body=[],
decorator_list=tree.decorator_list
)
return_call = Return(
Call(
func = Name(id=tree.name),
args = tree.args.args,
keywords = [],
starargs = tree.args.vararg,
kwargs = tree.args.kwarg
)
)
return_call = parse_stmt(unparse_ast(return_call))[0]
wrapper.body = [tree, return_call]
return wrapper
This can be used as follows:
>>> import macropy.core.console
0=[]=====> MacroPy Enabled <=====[]=0
>>> from macropy.my_macro import macros, recursive
>>> #recursive
... def fib(n):
... return n if n <= 1 else fib(n-1)+fib(n-2)
...
>>> foo = fib
>>> fib = foo(10)
>>> x = foo(8)
>>> x
21
It basically does exactly the wrapping that hus787 gave:
Create a new statement which does return fib(...), which uses the argument list of the original function as the ...
Create a new def, with the same name, same args, same decorator_list as the old one
Place the old function, together followed by the return statement, in the body of the new functiondef
Strip the original function of its decorators (I assume you'd want to decorate the wrapper instead)
The parse_stmt(unparse_ast(return_call))[0] rubbish is a quick hack to get stuff to work (you actually can't just copy the argument AST from the param list of the function and use them in a Call AST) but that's just detail.
To show that it's actually doing that, you can add a print unparse_ast statement to see what the transformed function looks like:
#macros.decorator()
def recursive(tree, **kw):
...
print unparse_ast(wrapper)
return wrapper
which, when run as above, prints
def fib(n):
def fib(n):
return (n if (n <= 1) else (fib((n - 1)) + fib((n - 2))))
return fib(n)
Looks like exactly what you want! It should work for any function, with multiple args, kwargs, defaults, etc., but I'm too lazy to test. Working with the AST is a bit verbose, and MacroPy is still super-experimental, but i think it's pretty neat.
I've got some code that looks like the following:
if command == 'a':
do_a(a, b, c)
elif command == 'b':
do_b(a, b, c)
elif command == 'c':
do_c(a, b, c)
How can I replace this type of thing with something more elegant? Perhaps, something along the lines of do_[command](a, b, c) where the function that is called is dependent upon the command?
Is it even possible?
You can store commands in a dict and lookup when needed:
In [15]: commands = {'mul': lambda x,y: x*y,
'add': lambda x,y: x+y}
In [16]: commands['mul'](3,4)
Out[16]: 12
In [17]: commands['add'](3,4)
Out[17]: 7
In [18]: command = 'add'; vars = (4,5)
In [19]: commands[command](*vars)
Out[19]: 9
you should check whether a command indeed is in commands:
if command in commands:
commands[command]()
else:
# handle error
You could do something like that using "reflection", calling the function by string name, like explained here:
Python: call a function from string name
BUT
That wouldn't be more elegant, it would be less readable, and easier to screw up if you don't have absolute control over what's passed as command.
Your version is just fine:
Explicit is better than implicit.
Simple is better than complex.
If you really want to avoid the elif's I would go with the dict of functions approach that was suggested in the comments.
Keep away from eval for things like this.
def do(fname):
return {'a':do_a, 'b':do_b, 'c':do_c}.get(fname)
def do_a(x,y,z): return x + y + z
def do_b(x,y,z): pass
def do_c(x,y,z): pass
Usage:
do('a')(1,2,3)
6
I'm waiting for a better solution from others but:
def dispatch(cmd, *args):
globals()['do_' + cmd](*args)
def do_a(a, b, c):
Usage:
dispatch('a', 1, 2, 3)
Obviously not robust but dispatch could make sure that the function exists.
Possibly a nice way would be to use decorators.
#command()
def do_a(a,b,c):
...
#command("do_x")
def myfunc(a, b, c):
...
Your decorator could maintain the dispatch lookup table etc.
It depends how worried you are that there might be a need to use existing functions or worry about name collisions.
This might help you, here souce can be any generic module path ending with function name like
module.funcname
So a sample call would look like convertStringToFunction(module.funcname)
def import_module(name):
mod = __import__(name)
components = name.split('.')
for comp in components[1:]:
mod = getattr(mod, comp)
return mod
def convertStringToFunction(source):
tempArr = source.rsplit('.',1)
mod = import_module(tempArr[0])
func = getattr(mod, tempArr[1])
return func
I have a function that returns a number. I want to assign a variable to have this value, but python gives a runtime error when I say temp = foo(i, j) : NameError: name 'foo' is not defined. Note that I've changed the function bodies of bar and foo around, obviously having a function that just returns 1 is useless, but it doesn't change my error.
sum = 0
for i in range(2, 100):
for j in range(2, i):
temp = foo(i, j)
if (temp > 100):
sum = sum + 1
print sum
def bar (n, a):
r = 1
return r
def foo (n, a):
s = bar(n, a)/factorial(5);
return s
def factorial (n):
r = 1
for i in range (2, n + 1):
r *= i;
return r
Names in Python do not exist until they are bound. Move the def foo(...): block above the code that uses foo().
Your definition of foo is AFTER you use it in the file. Put your function definition above the for loop.
As per other answers, your issue is the order in which you run your code: foo hasn't been defined yet when you first call it. Just wanted to add a comment about best practices here.
I always try to put everything in a function and then call any scripts at the bottom. You've probably encountered this pattern before, and it's a good habit to get into:
CONSTANT = 5
def run():
for i in xrange(CONSTANT):
print foo(i) # whatever code you want
def foo(n):
# some method here...
pass
if __name__ == "__main__":
run()
if you run this with python script.py or by hitting f5 in idle, run() will be executed after everything is defined.
By following this pattern you don't have to worry about the order you define your functions in, and you get the added benefit of being able to import foo with other functions without having your script execute during the import, which is probably not a desired behavior.