This is a piece of my code...
def contactMaster(data="",url= str(chosenMaster)+"todolist"):
print "url: "+url
It prints only "todolist" instead of "http://www.mysite.com/blah/1234/todolist"
Why isn't it working??
Default arguments are evaluated when the function is defined not when it is executed. So if chosenMaster is empty when Python defines contactMaster, it will print only todolist.
You need to move str(chosenMaster) into the function.
See Default Argument Values in the Python Tutorial for more info. The example there is:
The default values are evaluated at the point of function definition in the defining scope, so that
i = 5
def f(arg=i):
print arg
i = 6
f()
will print 5.
The function definition captures the value of chosenMaster at the time the function is declared, not when the function is called.
Do this instead:
def contactMaster(data='', url=None):
if url is None:
url = str(chosenMaster) + 'todolist'
print 'url: ' + url
Because default function arguments are determined when the function is defined. Changing chosenMaster after the fact will have no effect.
Related
I want to call that function by extracting the first word from the string. For example my string is like:
"my_func arg_1 arg_2"
# ^ ^ ^ second argument of function
# ^ ^ first argument of function
# ^ name of the function
where my_func is a name of the function already defined.
Based on the above mention string, I want to dynamically execute the my_func function. So, my function call should be like:
my_func(arg_1, arg_2)
Currently I am trying to achieve this via using eval:
eval(command.split(' ', 1)[0])
How can I achieve this?
You may use locals() (or globals()) to fetch the reference of function based on string. Below is the sample example:
# Sample function
def foo(a, b):
print('{} - {}'.format(a, b))
# Your string with functions name and attributes
my_str = "foo x y"
func, *params = my_str.split()
# ^ ^ tuple of params string
# ^ function name string
Now, pass the function string as a key to the locals() dict with *params as argument to the function as:
>>> locals()[func](*params)
x - y # output printed by `foo` function
Regarding the split method, by default the delimiter is space so you don't actually need to define that your delimiter is space and as you want the first item in the list, you just need to type the index 0 [0].
locals returns a dictionary with a current local symbol table. globals returns a dictionary with global symbol table.
var = "my_func arg_1 arg_2"
print (locals()[var.split()[0]]())
Or
var = "my_func arg_1 arg_2"
print (globals()[var.split()[0]]())
If the function was part of an object you could use the getattr built-in function.
var = "my_func arg_1 arg_2"
getattr(object, var.split()[0])
getattr(object, name[, default])
Return the value of the named
attribute of object. name must be a string. If the string is the name
of one of the object’s attributes, the result is the value of that
attribute. For example, getattr(x, 'foobar') is equivalent to
x.foobar. If the named attribute does not exist, default is returned
if provided, otherwise AttributeError is raised.
If you define you functions up front you can have greater control over their name mapping.
def my_func(a):
print(a)
functions = {'my_func': my_func}
def exe(text):
command = text.split(" ")
f = command[0]
args = command[1:]
if f in functions:
functions[f](args)
exe("my_func arg_1 arg_2")
Something along the lines of:
Check if the function exists inside the local scope.
If it does exist then run it using eval().
def add():
print("do something")
def find_function(funct_name, defined_names):
if defined_names.get(funct_name) is None:
print("no function called {}".format(funct_name))
return
eval(funct_name + "()")
# access local user defined names.
defined_names = locals()
#print(defined_names)
function_name = 'add'
find_function(function_name ,defined_names)
Output:
do something
I am trying to use the left-side argument's value in the below function inside of the default argument value to the right.
def function(var, vartwo = var*2):
return vartwo
print(function(7)) #should print 14
print(function(7,6)) #should print 6
However I am getting NameError: name 'var' is not defined. Is it not possible use an argument's value in a default argument value in Python? How would you suggest I tackle this problem?
It's not possible; how about this?
def function(var, vartwo = None):
if vartwo is None:
vartwo = var*2
return vartwo
print(function(7))
print(function(7,6))
The hack is to set the default value to None, then set it internally. If not none, then return whatever was entered by the user.
Pass the buck:
def function(var, *args):
return (lambda var, vartwo=var * 2: vartwo)(var, *args)
print(function(7)) # should print 14
print(function(7, 6)) # should print 6
I know about lambda functions but mind adding explanation?
Since we can't use var in vartwo's definition, we delay by setting up a new argument list, via a lambda, where var is now defined and the default for vartwo is legal.
I've made this somewhat confusing by reusing the var variable name to represent two different variables (a formal parameter to function and a formal parameter to lambda) and also act as a positional place holder.
I could, and probably should, have written this more simply as:
def function(var, *args):
return (lambda vartwo=var * 2: vartwo)(*args)
But I wanted to retain the flavor of the original problem.
What your doing won't work because var hasn't been declared. Here's a different approach:
def function(var, multiply=False):
if multiply:
return var * 2
else:
return var
print(function(7, True)) # 14
print(function(6)) # 6
No, it is not possible to use a value that is not defined outside of the function as a argument value for that function.
For an alternative, I'm late to the party, but how about something short and simple that will work if None is the second parameter?
def function(var, *args):
return args[0] if args else var * 2
print(function(7)) # prints 14
print(function(7, 6)) # prints 6
print(function(7, None)) # prints 'None'
Here, args is the list of arguments provided after var, and could be an empty list. We then return the first element of this list if the list is not empty (which is equivalent to the second argument). If the list is empty, we return var * 2.
The caveat here is that this will not throw the appropriate error if more than two arguments are provided. You can choose to manually raise a TypeError if len(args) > 1 (remembering that args are parameters after the first one) if this is important to enforce.
It is not possible to use the value of another argument in default value. The reason is very simple: the default values are evaluated exactly once: at the time when the function definition was executed.
One common pattern to use is to have the second argument be set to a special sentinel value by default, then test if the argument was set again within the function:
SENTINEL = object()
def function(var, vartwo=SENTINEL):
# was vartwo set?
if vartwo is not SENTINEL:
return vartwo
return var * 2
This way the function would return vartwo correctly even when you'd pass in None or any other value for it, unless you specifically passed the SENTINEL constant.
So I was reading this wonderful piece which tries to explain decorators in python.
My question is specific to this code snippet.
def surround_with(surrounding):
"""Return a function that takes a single argument and."""
def surround_with_value(word):
return '{}{}{}'.format(surrounding, word, surrounding)
return surround_with_value
def transform_words(content, targets, transform):
"""Return a string based on *content* but with each occurrence
of words in *targets* replaced with
the result of applying *transform* to it."""
result = ''
for word in content.split():
if word in targets:
result += ' {}'.format(transform(word))
else:
result += ' {}'.format(word)
return result
markdown_string = 'My name is Jeff Knupp and I like Python but I do not own a Python'
markdown_string_italicized = transform_words(markdown_string, ['Python', 'Jeff'],
surround_with('*'))
print(markdown_string_italicized)
What I don't understand is how did the function surround_with() get the variable word (when passed on by transform(word) inside transform_words()) in it's scope? I mean we have only declared a holding variable (as a function argument) for what the surrounding value should be and nothing else. Then how was word available to it?
What am I missing here?
The surround_with() function returns another function object with a closure:
def surround_with(surrounding):
"""Return a function that takes a single argument and."""
def surround_with_value(word):
return '{}{}{}'.format(surrounding, word, surrounding)
return surround_with_value
So surround_with_value is returned; it is this function that prepends and appends the value of surrounding to whatever is passed in:
>>> def surround_with(surrounding):
... """Return a function that takes a single argument and."""
... def surround_with_value(word):
... return '{}{}{}'.format(surrounding, word, surrounding)
... return surround_with_value
...
>>> function = surround_with(' foo ')
>>> function
<function surround_with_value at 0x108ac16e0>
>>> function('bar')
' foo bar foo '
The surround_with_value() function was returned and a reference to it was stored in the name function. That function object references surrounding as a closure:
>>> function.__closure__
(<cell at 0x108a8a590: str object at 0x1074c4060>,)
>>> function.__closure__[0].cell_contents
' foo '
and each time you call it that closure is dereferenced and the contents are used.
So surround_with() produces a function object, and such function (as the result of surround_with('*')), is passed to transform_words() as the 3rd argument:
transform_words(markdown_string, ['Python', 'Jeff'],
surround_with('*'))
so it is assigned to the variable transform:
def transform_words(content, targets, transform):
Thus, each time you call transform, you really are calling the nested surround_with_value() function with '*' as the surrounding closure, and word is being passed in:
result += ' {}'.format(transform(word))
I think I understood it,
When we call surround_with('*'), it returns the function surround_with_value() which is then returning the value '{}{}{}'.format('*', word, '*').
Now the very same function takes an argument (word here) which is then passed inside transform_words() and renamed as transform().
Inside it we finally pass the value for word.
Closure can be very confusing and this example might not be the best to show why surround_with_value() remembers surround with(surrounding) event if it's not in its scope.
I strongly advice you to read this excellent blog showing all concept you need to understand to understand decorators. Step1: Scope-->Step2: Closure-->Step3: Decorators
Take some time and read it from the beginning.
http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/
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.
I am trying to print a procedure in Python. How do I print it?
Here is my code
def proc(a,b):
if test(a):
return b
return a
print proc(a,b)
But I get this error:
NameError: name 'a' is not defined
Thanks in advance.
a is the name of the local variable used to hold the value of the first argument passed to the function when it is called. When actually calling it, you need an actual value, or a variable defined in the scope where the function is called. For example:
def proc(a,b):
if test(a):
return b
return a
x = 6
print proc(x, 7)
Now when proc is called, the value of the variable x and the value 7 are passed to proc. Inside proc, a will have the same value as x (at the time of the call) in the calling scope, and similarly b will have the value 7.
If you're trying to call proc and view the result, then there are two things you need to know:
You call a function by typing its name, followed by a pair of parentheses that contains the function's arguments: proc(23, 42)
You can print the result of an expression by typing print, followed by a pair of parentheses containing the expression: print(4 + 8 * sqrt(15) - 26).
Combine these two principles to view the result of a function call.
print(proc(23, 42))