Checking what function was passed into a function - python

I have a function that takes a function as one of its arguments, but depending on the context that function could be one of several (they are all comparator functions for creating rules for the sorted method). Is there any way to check which function was passed into a function? What I'm thinking is some kind of conditional logic like this:
def mainFunction (x, y, helperFunction):
if helperFunction == compareValues1():
do stuff
elif helperFunction == compareValues2():
do other stuff
etc. Would this work? Would I need to pass in all of the arguments for the function when checking for its existence? is there a better way?

You are on the right track, you just need to remove those parentheses:
def mainFunction (x, y, helperFunction):
if helperFunction == compareValues1(): <-- this actually CALLS the function!
do stuff
elif helperFunction == compareValues2():
do other stuff
Instead you would want
def mainFunction (x, y, helperFunction):
if helperFunction is compareValues1:
do stuff
elif helperFunction is compareValues2:
do other stuff

>>> def hello_world():
... print "hi"
...
>>> def f2(f1):
... print f1.__name__
...
>>> f2(hello_world)
hello_world
its important to note this only checks the name not the signature..

helperFunction==compareValues1

Since functions are itself an object in python, So, when you pass a function to your function, a reference is copied to that parameter.. So, you can directly compare them to see if they are equal: -
def to_pass():
pass
def func(passed_func):
print passed_func == to_pass # Prints True
print passed_func is to_pass # Prints True
foo = func # Assign func reference to a different variable foo
bar = func() # Assigns return value of func() to bar..
foo(to_pass) # will call func(to_pass)
# So, you can just do: -
print foo == func # Prints True
# Or you can simply say: -
print foo is func # Prints True
So, when you pass to_pass to the function func(), a reference to to_pass is copied in the argument passed_func

Related

How can I make a function that will called from inside a loop and that will indicate whether to continue?

def x():
# Go through series of checks. Then in one of the conditional if statement.
if y > x:
return continue
while True:
# Bunch of class attribute updates and checks.
x()
When a function is called in a loop, if certain conditions are achieved, return a result that will make the loop go back to the beginning, as if a continue is being called.
Just take it as a variable:
def x():
# Go through series of checks. Then in one of the conditional if statement.
if y > x:
return True
while True:
# Bunch of class attribute updates and checks.
should_continue = x()
if should_continue:
continue
make a function that return a boolean variable , then after that function invocation use if to check the variable
let's make an example to clarify:
you have this function
x(){
var check=false;
...
do something
...
if(num==5){
check=true;
}
return check;
}
your loop must be something like this:
while(true){
...
...
stop=x()
if(stop==false){
group of instructions you want to skip
...
...
...
}
}

How to pass function as an argument to another function, without running it automatically

I have 2 functions - one that is checking object status and the second one that is creating some connections when allowed. I'm trying to pass a function as an argument, but return that only when conditions will be correct. The issue is it is running anyway.
testList = []
def testObject(name, funct):
if name == "testName":
b = funct
return name + str(b)
else:
return None
def someFunction(vector, opt, axis):
testList.append("Something")
return opt * axis
a = testObject("testName2", someFunction([0,0,0], 1, 6) )
print a
print testList
Output:
print a
print testList
None
['Something']
So even if "A" is current, testList should be empty.
Wonder what I'm doing wrong.
The problem is that you are calling your function when you're trying to pass it as a parameter. Instead of passing it as someFunction(...), pass it as someFunction.
e.g.
a = testObject("testName2", someFunction )
instead of what you have. This will pass the function 'object', ready to be called. Then, inside the other function, simply do:
def testObject(name, funct):
if name == "testName":
b = funct([0,0,0], 1, 6)
I assume you'd want to pass the values as different arguments, as I assume these aren't constants, but this should be enough to guide you.
If you want to pass it in with arguments already set, I'd definitely give a look into functools.partial, but keep in mind that it might become a bit messy.
For partial:
from functools import partial
partial_function = partial(someFunction, [0,0,0], 1, 6)
a = testObject("testName2", partial_function )
------
def testObject(name, funct):
if name == "testName":
b = funct()

pass a function name as argument and then check correctness

I'm aware that I cann pass a function name as an argument to another function i.e
def fun_passed(a,b):
#do something
def main_fun(arg,fun_passed):
#do something
#call main_fun
first_fun =fun_passed
main_fun(1,first_fun)
Inside main_fun how can I make some checks.
For example, Based on the function i passed i want to set a variable
def main_fun(1,fun_passed):
if fun_passed==first_fun:
i=1
else:
i=10
I can't simply use == because i think that comparison doesn't make sense.
Thanks
You can compare functions for equality, but it's not going to check if the two functions do the exact same thing. Such a check is, in general, undecidable in the technical sense.
Instead, f == g simply returns true if both f and g return to the same underlying object (i.e., it's the same as f is g). This means that something as simple as (lambda x: x) == (lambda x: x) evaluates as False.
You should use the is keyword:
def fct_a(a,b):
#do something
pass
def fct_b(a,b):
#do something
pass
def main_fun(fct):
if fct is fct_a:
print("fct is 'fct_a'")
else:
print("fct is not 'fct_a'")
main_fun(fct_a) # >> fct is 'fun_passed'
main_fun(fct_b) # >> fct is not 'fun_passed'
For more about the differences between is and ==, see there
If you are dealing with functions, not a lambda, the function object has a variable __name__ which shows the exact name of the original function. Here a simple example:
>>> def x():
... return 0;
...
>>> type(x)
<type 'function'>
>>> x.__name__
'x'
>>> y=x
>>> y.__name__
'x'
So in your case, it will be something like this
if fun_passed.__name__=="first_fun":

How to access a Python function using it's __name__?

I have a function func :
def func(a):
print a
func.__name_ = "My_Function"
To get the name of the function I will just do func.__name__.
But is there a way to call func() by using its name i.e. "My_Function"?
Edit: There are going to be large number of functions for which this has to be done. Is there any better solution apart from keeping a mapping of function.name to the function. ?
It will be much easier to use a dictionary:
def func():
print('func')
func_dict = {"My_Function": func}
func_dict["My_Function"]()
# 'func'
Assuming that you want to access functions that are defined in global scope (not part of any class/object):
def foo():
print "foo"
def bar():
print "bar"
foo.__name__ = "1"
bar.__name__ = "2"
# locals().items() will return the current local symbol table, which is an iterable and
# it contains the globally defined functions.
symbol_table = locals().items()
# we will generate a list of functions that their __name__ == "1"
one_functions = [value for key, value in symbol_table if callable(value) and value.__name__ == "1"]
# now we can call the first item on the list - foo()
one_functions[0]()

Python - Passing a function into another function [duplicate]

This question already has answers here:
Python function as a function argument?
(10 answers)
Closed last month.
I am solving a puzzle using python and depending on which puzzle I am solving I will have to use a special set of rules. How can I pass a function into another function in Python?
Example
def Game(listA, listB, rules):
if rules == True:
do...
else:
do...
def Rule1(v):
if "variable_name1" in v:
return False
elif "variable_name2" in v:
return False
else:
return True
def Rule2(v):
if "variable_name3" and "variable_name4" in v:
return False
elif "variable_name4" and variable_name1 in v:
return False
else:
return True
This is just a pseudo code and therefore not specific but I get the code to compile but I need to know how to call the function Game and whether it's correctly defined since rules will be switched for either Rule1(v) or Rule2(v).
Just pass it in like any other parameter:
def a(x):
return "a(%s)" % (x,)
def b(f,x):
return f(x)
print b(a,10)
Treat function as variable in your program so you can just pass them to other functions easily:
def test ():
print "test was invoked"
def invoker(func):
func()
invoker(test) # prints test was invoked
For passing both a function, and any arguments to the function:
from typing import Callable
def looper(fn: Callable, n:int, *args, **kwargs):
"""
Call a function `n` times
Parameters
----------
fn: Callable
Function to be called.
n: int
Number of times to call `func`.
*args
Positional arguments to be passed to `func`.
**kwargs
Keyword arguments to be passed to `func`.
Example
-------
>>> def foo(a:Union[float, int], b:Union[float, int]):
... '''The function to pass'''
... print(a+b)
>>> looper(foo, 3, 2, b=4)
6
6
6
"""
for i in range(n):
fn(*args, **kwargs)
Depending on what you are doing, it could make sense to define a decorator, or perhaps use functools.partial.
Just pass it in, like this:
Game(list_a, list_b, Rule1)
and then your Game function could look something like this (still pseudocode):
def Game(listA, listB, rules=None):
if rules:
# do something useful
# ...
result = rules(variable) # this is how you can call your rule
else:
# do something useful without rules
A function name can become a variable name (and thus be passed as an argument) by dropping the parentheses. A variable name can become a function name by adding the parentheses.
In your example, equate the variable rules to one of your functions, leaving off the parentheses and the mention of the argument. Then in your game() function, invoke rules( v ) with the parentheses and the v parameter.
if puzzle == type1:
rules = Rule1
else:
rules = Rule2
def Game(listA, listB, rules):
if rules( v ) == True:
do...
else:
do...

Categories

Resources