i am trying to write a function to check if a parameter was passed to it (which is a function ) if so call that function with an argument else if there wasn't any argument given return a value so my approach was like this :
def nine(fanc=None):
if(fanc!=None): return fanc(9,fanc)
return 9
but this code rise an error which is :
TypeError: 'int' object is not callable
i know that this approach isn't correct but i couldn't find any other way to do so
i have also tried using *args this way but end up with the same results :
def nine(*args):
if(len(args)!=0): return args[0](9,args)
return 9
I try to guess what you want but this snippet might help you:
def fct(**kwargs):
if 'func' in kwargs:
f = kwargs['func']
return f(9)
else:
return 9
def f(x):
return x**2
print(fct()) # result = 9
print(fct(func=f)) # result = 81
You might use callable built-in function, consider following example
def investigate(f=None):
if callable(f):
return "I got callable"
return "I got something else"
print(investigate())
print(investigate(min))
output:
I got something else
I got callable
Beware that callable is more broad term that function, as it also encompass objects which have __call__ method.
If you want to check whether the passed argument is a function and, if yes, then execute it with fixed arguments, you could try the following:
from typing import Union
from types import FunctionType
def nine(func: Union[FunctionType, None] = None):
if type(func) is FunctionType:
return func(9)
return 9
Related
I get a TypeError: 'str' object is not callable error when a decorator function is caleld. E.g. I
call the function msgReturnAsList, which is actually meant to return a list and therefore I do not understand why is it throwing an error that a str object is not callable.
I read at FreeCodeCamp that this TypeError occurs mainly in two occasions, neither of which has anything to do with my case:
1."If You Use str as a Variable Name in Python"
2. "If You Call a String Like a Function in Python"
Can somebody clarify what is the logic behind this and how do I get msgReturnAsList to return the string converted to upper by wrapThis and then converted to a list by the problematic decorator function msgReturnAsList?
def wrapThis(a):
a = str(a).upper()
return a
#wrapThis
def msgReturnAsList(msg):
msg = list(msg)
return msg
b = "Convert to upper and output it as a list of letters."
print(msgReturnAsList(b))
I tired changing the list to string, interestingly the error remains the same.
A decorator method should return a method:
def wrapThis(func):
def wrapper_func(msg):
msg = str(msg).upper()
return func(msg)
return wrapper_func
#wrapThis
def msgReturnAsList(msg):
msg = list(msg)
return msg
b = "Convert to upper and output it as a list of letters."
print(msgReturnAsList(b))
How to Create and Use Decorators in Python With Examples
Is there, in any python standard library package, a callable that, given an arg, returns a callable which always returns said arg?
What I'm looking for is basically an equivalent operator.itemgetter for the following function:
def constant_return(return_value):
return lambda *args, **kwargs: return_value
The main use-case I see right now would be to use it as the second argument of unittest.mock.patch when decorating a test case
You could do something like this using partial:
from functools import partial
def constant_return(return_value):
def constant_return_value(return_value):
return return_value
return partial(constant_return_value, return_value)
cr = constant_return(5)
cr()
# outputs 5
This will make constant_return return a partial function with the nested function and the return value you passed in. When called, the returned callable will return the value you initially passed in.
Or better yet, using lambda:
def constant_return(return_value):
return partial(lambda x: x, return_value)
cr = constant_return(5)
cr()
# Outputs 5
I have a class. This class has a list of functions that are to be evaluated by a different program.
class SomeClass(object):
def __init__(self, context):
self.functions_to_evaluate = []
There is a function that adds functions to an instance of SomeClass, via something like:
new_function = check_number(5)
SomeClassInstance.functions_to_evaluate.append(new_function)
Where check_number is a function that will check if number is greater than 10, let's say.
If I take SomeClassInstance.functions_to_evaluate and print it, I get a bunch of python objects, like so:
<some_library.check_number object at 0x07B35B90>
I am wondering if it is possible for me to extract the input given to check_number, so something like:
SomeClassInstance.functions_to_evaluate[0].python_feature() that will return "5" or whatever the input to check_number was to me.
You can use the standard library functools.partial, which creates a new partially applied function *.
>>> from functools import partial
>>> def check_number(input):
... return input > 10
>>> fn = partial(check_number, 5)
>>> fn.args # this attribute gives you back the bound arguments, as a tuple.
(5,)
>>> fn() # calls the function with the bound arguments.
False
*: actually the partial object is not a function instance, but it is a callable, and from a duck-type perspective it's a function.
If new_function = check_number(5) is a closure, then you can extract this value using __closure__[0].cell_contents:
Example:
def foo(x):
def inn(y):
return x
return inn
s = foo(5)
print(s.__closure__[0].cell_contents)
Output:
5
I understand your confusion, but:
new_function = check_number(5)
Is calling the function, and the new_function variable gets assigned the return value of the function.
If you have this check_number function:
def check_number(input):
return input > 10
Then it will return False, and new_function will be False. Never <some_library.check_number object at 0x07B35B90>.
If you're getting <some_library.check_number object at 0x07B35B90> then your check_number() function is returning something else.
There are probably several ways to skin this cat. But I'd observe first and foremost that you're not adding python function objects to the functions_to_evaluate list, you're adding the evaluations of functions.
You could simply add a tuple of function, args to the list:
SomeClassInstace.functions_to_evaluate.append((check_number, 5))
And then you can:
for f, args in SomeClassInstance.functions_to_evaluate:
print(args)
Just reading the Python doc's in particular this page, in regards to attrgetter and itemgetter.
I'm struggling to understand the usage of the usage of def and return in the code examples. Not the usage of those functions.
It seems like a lamdba, but I don't know how to interpret it.
EDIT
I think it just clicked. The attrgetter is like a constructor for the resolve_attr function? This was a little confusing, as i'd normally expect the code for a def to be between the def and the return. The code on the return is like a lambda. To add to the confusion the arg ojb is the argument passed to the returned object. Arhhhhh.....
What do i need to know for this to make sense?
This is the code example I'm referring to:
def attrgetter(*items):
if any(not isinstance(item, str) for item in items):
raise TypeError('attribute name must be a string')
if len(items) == 1:
attr = items[0]
def g(obj): #What is this
return resolve_attr(obj, attr)
else:
def g(obj):#And this?
return tuple(resolve_attr(obj, attr) for attr in items)
return g
def resolve_attr(obj, attr):
for name in attr.split("."):
obj = getattr(obj, name)
return obj
def is the keyword to define a function.
These are just functions defined inside another function attrgetter()
That's why you have multiple return inside attrgetter()
g looks like lambda because attrgetter() returns a function, and not the result directly.
g could be replaced by a lambda declaration indeed.
In Python, functions are just like normal object. You can pass them around, and (as in the example above) return them from other functions.
The example function, returns another function as its return value. It does so by defining a function (that's the def g(ojb): line) and then simply returning it.
You can do this, because in Python - a function is just like any other object.
def apply_twice(func,arg):
return func(func(arg))
def add_five(x):
return x+5
print (apply_twice(add_five,10))
The output I get is 20.
This one is actually confusing me like how is it working.Can anybody explain me how this is working by breaking it down
The function apply_twice(func,arg) takes two arguments, a function object func and an argument to pass to the function func called arg.
In Python, functions can easily be passed around to other functions as arguments, they are not treated differently than any other argument type (i.e first class citizens).
Inside apply_twice, func is called twice in the line:
func(func(arg))
Which, alternatively, can be viewed in a more friendly way as:
res = func(arg)
func(res)
If you replace func with the name of the function passed in add_five you get the following:
res = add_five(arg) # equals: 15
add_five(res) # result: 20
which, of course, returns your expected result.
The key point to remember from this is that you shouldn't think of functions in Python as some special construct, functions are objects just like ints, listss and everything else is.
Expanding the code it executes as follows, starting with the print call:
apply_twice(add_five,10))
add_five(add_five(10)) # add_five(10) = 15
add_five(15) # add_five(15) = 20
Which gives you the result: 20.
When apply_twice is called, you are passing in a function object and a value. As you can see in the apply_twice definition, where you see func that is substituted with the function object passed to it (in this case, add_five). Then, starting with the inner func(arg) call, evaluate the result, which is then passed to add_five again, in the outer return func( ... ) call.
What you need to understand here is that
apply_twice(func,arg)
is a higher function which accepts two arguments (another function named func and an argument arg). The way it works is that it first evaluate the value of the other function, then use the value as an argument inside the higher function.
remember we have a function add_five(x) which add 5 to the argument supply in it...
then this function add_five(x) is then passed as an argument to another function called
apply_twice_(func,arg) which return func(func(arg)).
now splitting func(func(arg)) we have
func(arg) #lets called it a
then func(func(arg))==func(a) since a = func(agr)
and (a) is our add_five(x) function, after it add 5, then the value we got is re-used as another fresh argument to add another 5 to it, that is why we have 20 as our result.
Another example is:
def test(func, arg):
return func(func(arg))
def mult(x):
return x * x
print(test(mult, 2))
which give 16 as result.