function pointers in python - python

I would like to do something like the following:
def add(a, b):
#some code
def subtract(a, b):
#some code
operations = [add, subtract]
operations[0]( 5,3)
operations[1](5,3)
In python, is it possible to assign something like a function pointer?

Did you try it? What you wrote works exactly as written. Functions are first-class objects in Python.

Python has nothing called pointers, but your code works as written. Function are first-class objects, assigned to names, and used as any other value.
You can use this to implement a Strategy pattern, for example:
def the_simple_way(a, b):
# blah blah
def the_complicated_way(a, b):
# blah blah
def foo(way):
if way == 'complicated':
doit = the_complicated_way
else:
doit = the_simple_way
doit(a, b)
Or a lookup table:
def do_add(a, b):
return a+b
def do_sub(a, b):
return a-b
handlers = {
'add': do_add,
'sub': do_sub,
}
print handlers[op](a, b)
You can even grab a method bound to an object:
o = MyObject()
f = o.method
f(1, 2) # same as o.method(1, 2)

Just a quick note that most Python operators already have an equivalent function in the operator module.

Related

How would I run a function given its name?

I have a large number of blending functions:
mix(a, b)
add(a, b)
sub(a, b)
xor(a, b)
...
These functions all take the same inputs and provide different outputs, all of the same type.
However, I do not know which function must be run until runtime.
How would I go about implementing this behavior?
Example code:
def add(a, b):
return a + b
def mix(a, b):
return a * b
# Required blend -> decided by other code
blend_name = "add"
a = input("Some input")
b = input("Some other input")
result = run(add, a, b) # I need a run function
I have looked online, but most searches lead to either running functions from the console, or how to define a function.
I'm not really big fan of using dictionary in this case so here is my approach using getattr. although technically its almost the same thing and principle is also almost the same, code looks cleaner for me at least
class operators():
def add(self, a, b):
return (a + b)
def mix(self, a, b):
return(a * b)
# Required blend -> decided by other code
blend_name = "add"
a = input("Some input")
b = input("Some other input")
method = getattr(operators, blend_name)
result = method(operators, a, b)
print(result) #prints 12 for input 1 and 2 for obvious reasons
EDIT
this is edited code without getattr and it looks way cleaner. so you can make this class the module and import as needed, also adding new operators are easy peasy, without caring to add an operator in two places (in the case of using dictionary to store functions as a key/value)
class operators():
def add(self, a, b):
return (a + b)
def mix(self, a, b):
return(a * b)
def calculate(self, blend_name, a, b):
return(operators.__dict__[blend_name](self, a, b))
# Required blend -> decided by other code
oper = operators()
blend_name = "add"
a = input("Some input")
b = input("Some other input")
result = oper.calculate(blend_name, a, b)
print(result)
You can create a dictionary that maps the function names to their function objects and use that to call them. For example:
functions = {"add": add, "sub": sub} # and so on
func = functions[blend_name]
result = func(a, b)
Or, a little more compact, but perhaps less readable:
result = functions[blend_name](a, b)
You could use the globals() dictionary for the module.
result = globals()[blend_name](a, b)
It would be prudent to add some validation for the values of blend_name

How to update pure function?

I'm trying to do the following: I want to write a function translate(f, c) that takes a given function f (say we know f is a function of a single variable x) and a constant c and returns a new function that computes f(x+c).
I know that in Python functions are first-class objects and that I can pass f as an argument, but I can't think of a way to do this without passing x too, which kind of defeats the purpose.
The trick is for translate to return a function instance.
def translate(f, c):
def func(x):
return f(x + c)
return func
Now the variable x is "free", and the names f and c are coming from an enclosing scope.
What about this?
def translate_func(f, c):
return lambda x: f(x + c)
To be used like, e.g.:
import math
g = translate_func(math.sin, 10)
print(g(1) == math.sin(10 + 1))
# True
EDIT
Note that this design pattern of a function taking a function as a parameter and returning another function is quite common in Python and goes by the name of "function decoration", with an associated convenience syntax. See PEP318 for more info on it.
def transalte(f, c):
def _inner(x):
return f(x+c)
return _inner

Checking if the value of a string is true - python

I am trying to see if a string is true or false but im stuck... In the following code I have made a list of statements that I want to evaluate, I have put them in strings because the variables need to be declared after the list is .(Reason is that the list of statements to be evaluated are being passed as a parameter to a function, in this function the variables are declared) I want to run through all of the items in the list and if it is a true statement then do something... Here is my code: (There is no output generated)
a = ['b > c', 'b = c', 'b < c']
b = 5
c = 3
for item in a:
if exec(item):
print(item)
exec is a function in python3.x1 that returns None so you'll always have a falsy result. You probably want eval.
Also be careful here. Do not use this unless you completely trust the input strings as it will allow execution of arbitrary code otherwise.
Note that this is a very strange code design and there is probably a better way to accomplish what you want... For example:
Why do you want to define the strings before the variables are defined? Coupling strings to names in your code in this way is likely to lead to a painful code maintenance experience.
1In python2.x, this would fail with a SyntaxError since exec was a statement prior to python3.x
Having tried to understand your use-case a little more, I would propose that you create an API where you pass functions.
def f1(a, b, **kwargs):
return a > b
def f2(a, b, **kwargs):
return a == b
def f3(a, c, **kwargs):
return a <= c
funcs = [f1, f2, f3]
Now you can define a function that will pass the parameters. You'll need to define which parameters it intends to pass -- but it will always pass them all:
def func_caller(funcs):
param_map = {
'a': get_a_somehow(),
'b': get_b_somehow(),
'c': get_c_somehow(),
...
}
for func in funcs:
if func(**param_map):
print("Hello World!")
There are other way to make the "contract" between func_caller and the functions that it is calling even more binding (e.g. pass the params as a more structured object like a namedtuple).
from collections import namedtuple
FuncCallerParams = namedtuple('FuncCallerParams', 'a,b,c')
def f1(func_caller_params):
return func_caller_params.a > func_caller_params.b
...
funcs = [f1, f2, ...]
def func_caller(funcs):
a = ...
b = ...
c = ...
fcp = FuncCallerParams(a, b, c)
for func in funcs:
if func(fcp):
...

Creating a new function as return in python function?

I was wondering if it is possible in python to do the following:
def func1(a,b):
return func2(c,d)
What I mean is that suppose I do something with a,b which leads to some coefficients that can define a new function, I want to create this function if the operations with a,b is indeed possible and be able to access this outside of func1.
An example would be a simple fourier series, F(x), of a given function f:
def fourier_series(f,N):
...... math here......
return F(x)
What I mean by this is I want to creat and store this new function for later use, maybe I want to derivate it, or integrate or plot or whatever I want to do, I do not want to send the point(s) x for evaluation in fourier_series (or func1(..)), I simply say that fourier_series creates a new function that takes a variable x, this function can be called later outside like y = F(3)... if I made myself clear enough?
You should be able to do this by defining a new function inline:
def fourier_series(f, N):
def F(x):
...
return F
You are not limited to the arguments you pass in to fourier_series:
def f(a):
def F(b):
return b + 5
return F
>>> fun = f(10)
>>> fun(3)
8
You could use a lambda (although I like the other solutions a bit more, I think :) ):
>>> def func2(c, d):
... return c, d
...
>>> def func1(a, b):
... c = a + 1
... d = b + 2
... return lambda: func2(c,d)
...
>>> result = func1(1, 2)
>>> print result
<function <lambda> at 0x7f3b80a3d848>
>>> print result()
(2, 4)
>>>
While I cannot give you an answer specific to what you plan to do. (Looks like math out of my league.)
I can tell you that Python does support first-class functions.
Python may return functions from functions, store functions in collections such as lists and generally treat them as you would any variable.
Cool things such as defining functions in other functions and returning functions are all possible.
>>> def func():
... def func2(x,y):
... return x*y
... return func2
>>> x = func()
>>> x(1,2)
2
Functions can be assigned to variables and stored in lists, they can be used as arguments for other functions and are as flexible as any other object.
If you define a function inside your outer function, you can use the parameters passed to the outer function in the definition of the inner function and return that inner function as the result of the outer function.
def outer_function(*args, **kwargs):
def some_function_based_on_args_and_kwargs(new_func_param, new_func_other_param):
# do stuff here
pass
return some_function_based_on_args_and_kwargs
I think what you want to do is:
def fourier_series(f,N):
#...... math here......
def F(x):
#... more math here ...
import math #blahblah, pseudo code
return math.pi #whatever you want to return from F
if f+N == 2: #pseudo, replace with condition where f,N turn out to be useful
return F
else:
return None
Outside, you can call this like:
F = fourier_series(a,b)
if F:
ans = F(x)
else:
print 'Fourier is not possible :('
The important thing from Python's point of view are:
Yes, you can write a function inside a function
Yes, you can return a function from a function. Just make sure to return it using return F (which returns the function object) as compared to return F(x) which calls the function and returns the value
I was scraping through some documentation and found this.
This is a Snippet Like your code:
def constant(a,b):
def pair(f):
return f(a,b)
return pair
a = constant(1,2) #If You Print variable-> a then it will display "<function constant.
#<locals>.pair at 0x02EC94B0>"
pair(lambda a, b: a) #This will return variable a.
Now, constant() function takes in both a and b and return a function called "Anonymous Function" which itself takes in f, and calls f with a and b.
This is called "closures". Closures is basically an Instance of a Function.
You can define functions inside functions and return these (I think these are technically closures):
def make_f(a, b):
def x(a, b):
return a+b
return x(a, b)

Python Get function parent attribute

I have a function in python that return an inner function
def parent_func(func):
def decorator(a,b):
return a + b
return decorator
for simplify lets consider this code
def in_func ( a, b)
return a*b
child = parent_func ( in_func)
Does someone know a way to get the "func" attribute of parent_func from child?
The func attribute only exists in the scope of the parent_func() function.
If you really need that value, you can expose it:
def parent_func(func):
def decorator(a,b):
return a + b
decorator.original_function = func
return decorator
Next question is, why would you want to do that?
What is the actual design problem behind this issue?
You can store it as an attribute on decorator before returning it.
>>> def parent_func(func):
... def decorator(a,b):
... return a + b
... decorator.func = func
... return decorator
...
>>> #parent_func
... def product(a, b):
... return a * b
...
>>> product.func
<function product at 0x000000000274BD48>
>>> product(1, 1)
2
You are slightly misusing decorators here. What is the point of writing a decorator which completely ignores the original function it is given?
Oh, I've also used the #foo decorator syntax, because it's cleaner. It's equivalent to what you have written, though.

Categories