In the Beaker documentation, they talk about not passing a parameter directly in the createfunc call but use a closure.
The creation function must not accept any arguments as it won’t be called with any. Options affecting the created value can be passed in by using closure scope on the creation function:
All examples and documentation I can find on closure hint toward a nested function call with the first taking in a variable. In this case I don't understand how to write the closure since its not a function but a key value variable.
results = tmpl_cache.get(key=search_param, createfunc=get_results)
How would I pass variable_a into get_results(variable_a) in the createfunc?
Like so, or similar?
get_results_func returns a function pointer that, because it's in a closure, will call get_results correctly.
def get_results_func(variable_a):
def call_get_results():
return get_results(variable_a)
return call_get_results # note the absence of brackets here.
results = tmpl_cache.get(key=search_param, createfunc=get_results_func(variable_a))
Related
I would like to know if it is a good practice to directly return a modified function parameter in Python. Example:
def next_business_day_(day)
while is_weekend(day):
day = day + datetime.timedelta(days=1)
return day
I often see functions written this way (see below), creating a separate variable to return. Is there any upside to do this? Other than the semantic meaning of the newly created variable name (i.e ret)?
def next_business_day(day)
ret = day
while is_weekend(ret):
ret = ret + datetime.timedelta(days=1)
return ret
Both function seem to work, but is there any downside using the first method? (i.e directly return the modified function parameter) which is more concise.
The issue is Python's function parameter evaluation strategy, which is not by value or by reference, but by object.
This by object evaluation strategy implies that you receive inside the function what you send when you make the call. If you pass a variable, you receive a variable but,
if you pass immutable arguments like integers, strings or
tuples to a function, the passing acts like call-by-value. The object
reference is passed to the function parameters. They can't be changed
within the function, because they can't be changed at all, i.e. they
are immutable.
So, your first case would work as long as you (or whoever uses your function) passes a variable as parameter (next_bussiness_day(day_var)), but it would fail if he or she passes an immutable (next_bussiness_day('sunday')).
So, the best practice is the second one.
https://www.python-course.eu/passing_arguments.php
I have the following problem:
I have a function that holds another function inside (see code bellow). I need to call the function getFastaEntry with a parameter filename set in the top level function.I tried to call it with generate_fasta_reader(filename).getFastaEntry(), but I get the error message "function object has no attribute getFastaEntry()". Can anybody tell me how I can call the inner function?
def generate_fasta_reader(filename, gzipped=False, strip=True):
def getFastaEntry():
filehandle = None
You must return the inner function. It's not accessible otherwise and in fact ceases to exist as soon as the function ends, because there are no references to it at that point. The parameters of the outer function are available to the inner function via a closure. (I assume your actual getFastaEntry() function actually does something besides assign a local variable that goes out of scope almost immediately.)
def generate_fasta_reader(filename, gzipped=False, strip=True):
def getFastaEntry():
filehandle = None
return getFastaEntry
Calling:
getter = generate_fasta_reader("foo.txt")
getter()
Or in one step (if you only need it call the inner function once per outer function call):
generate_fasta_reader("foo.txt")()
I am new to Python so I am unsure about the difference in variable assignment before or after the function definition.
Specifically, the first example was adopted from Lutz's book.
def tester(start):
print("inside tester")
def nested(label):
print("inside nested")
print(label,nested.state)
nested.state += 1
print("done with nested")
nested.state = start
print("done with tester")
return nested
F = tester(0)
F('spam')
F.state
F.state
The objective of the code is to store the state information without using nonlocal.
I am unsure what nested.state means here. I am unsure because nested.state is used inside nested() function (i.e. nested.state +=1) and outside nested() function (i.e. nested.state = start).
I modified the code above to see whether Python accepts assigning variable after function declaration for nested() and to see whether there is any concept I am missing relating to function.variable call (i.e. nested.state call).
def tester(start):
def nested(label):
print(label, state)
state += 1 #replaced 'nested.state' with 'state' here
state = start #replaced 'nested.state' with 'state' here
return nested
F=tester(0)
F('spam')
F('ham')
Unfortunately, above code generates error local variable 'state' referenced before assignment. This tells me that I am missing some concept about function.variable (i.e. nested.state).
Can someone please help me understand three things:
I. why it is that the code with nested.state doesn't generate any error but state does?
II. what does nested.state mean? If nested.state is a mechanism to access function's variables, why is it that the call inside nested() function also uses nested.state and not state?
III. If nested.state is a mechanism to access variable inside function, then why is it that PyCharm fails to show state under dropdown when I type nested.?
I'd appreciate any help. I research SO, and couldn't find any explanation on such problems.
The reason the first code example worked is because it was assigning and referencing an attribute of the nested function object. The key concept to understand here, is that Python allows you to assign new, arbitrary attributes to objects - including functions:
>>> def func(a, b):
return a + b
>>> func(1, 2)
3
>>> func.attr = 5
>>> func.attr
5
The first code example takes advantage of this fact by using the nested function object to store the necessary state. This is the same concept as using any other object to store the state. It's particularly convenient, however, to use a function since it's readily available.
In the second example, a normal variable is used. Because of this, normal scoping rules apply which means simply that the state variable defined in tester is not the state variable being referenced in nested. Thus, an error is raised.
Actually, I think you're asking a question about scope in Python, ignoring your code, check this:
def scope_level_1():
variable = 'Scope_level_1'
def scope_level_2():
variable = 'Scope_level_2'
def core():
nonlocal variable
variable += '_TOUCHED_AND_MODIFIED_BY_CORE'
print(variable)
return core()
return scope_level_2()
scope_level_1()
# 'Scope_level_2_TOUCHED_AND_MODIFIED_BY_CORE'
Don't worry about the keyword nonlocal, treat it just as a declaring to make code more readable.
First, remember a += b is the same as a = a + b. So a must exist before getting to the +=.
Simply put, in the first example the function nested has an attribute called state (accessed by nested.state). It is an attribute, which means that once you tell nested that it has an attribute called state (you are doing this in line 9 when nested.state = start) it keep that attribute. So, in the first example nested.state exists when you get to the +=.
In the second example, you are declaring a variable called state in tester, and another variable called state in nested. The one in nested could be called potato for all that matters, because it is not the same variable. Therefore when you arrive to the +=, the variable state does not exist!
I am a newbie to Python, i am having some doubts on working of below mentioned code snippet from shutil module.
def ignore_patterns(*patterns):
"""Function that can be used as copytree() ignore parameter.
Patterns is a sequence of glob-style patterns
that are used to exclude files"""
def _ignore_patterns(path, names):
ignored_names = []
for pattern in patterns:
ignored_names.extend(fnmatch.filter(names, pattern))
return set(ignored_names)
return _ignore_patterns
When a call to shutil.copytree is made with ignore option set to ignore_patterns, then it calls ignore_patterns function and returns a function. My doubts are:
1) ignore_patterns when called will return the _ignore_pattern function reference. Now when this function will be called, how is it still accessing the "patterns" list? Once called function "ignore_patterns" has returned, list patterns which was created at its call should be available for its called scope only.
2) What is the signicance of underscore in the returned function _ignore_patterns function name?
This is called a closure, and it's a general feature of languages that allow nested functions. Inner functions can close over variables in an outer scope, and will retain a reference to that name when they are called from outside the outer function.
The underscore is just to signify that _ignore_patterns is an inner function, while keeping the name of the returned function similar. It could be called anything you like.
ignore_patterns when called will return _ignore_pattern function reference. Now when this function will be called, how it is still accessing the "patterns" list.
This is fine. _ignore_pattern is a closure. That means it keeps around all the local variables (including function parameters) that it needs to do its job. Eventually the garbage collector will get it, but not while it might still be needed.
What is the signicance of underscore in returned function _ignore_patterns function name?
The author just wanted to disambiguate the names. It beats calling the closure f. Which is what I would have done.
is it possible to add a local varible to a function, just before calling it ? if yes how ?
EDIT:REASON
i noticed that all my views in django are using
render_to_response(template_name,locals())
now i created a middleware and i wanted to add one more local variable using the
def process_view():
method of it .so that i don't have to modify the views .
The local scope for a function does not exist until the function is called, so it's not possible to do this. You could do this for a closure, but the next person to have to maintain the code would hunt you down and kill you.
Although I also think it is pretty useless, I thought that you may enclose the function in either a 'with' statement or another function, like the code below. Of course, this approach can be accomplished directly within the function of interest. In fact, you are adding the local variable 'during' the function declaration. See if this fits your needs!
#!/usr/bin/python
def my_funct(_local):
"""My function of interest
"""
print "Local argument was %s" % str(_local)
return "Finished"
def localize(fct, local_var):
"""
"""
return fct(_local = local_var)
## Use function to 'localize' variable
localize(my_funct, local_var="LOCAL_VARIABLE")
## Same effect without supplementary function :
my_funct(_local="LOCAL_VARIABLE")
try:
print local_var
except:
print "No such global variable"
Just some thoughts :)
Cheers
So if you’re one of those lazy
programmers and you like keeping code
particularly concise, you can take
advantage of a built-in Python
function called locals(). It returns a
dictionary mapping all local variable
names to their values, where “local”
means all variables that have been
defined within the current scope.
source
It is a trick in order to not have to explicitly list all of the variables you need to pass in to the function. In this case, you need to explicitly state a variable to pass in. Therefore, you should not be using locals() in the calls you are making in your middle-ware, as the trick was not designed to be used like that.
i mangaged to do that using decorators.