do not understand closures question in python - python

def a(b=[]):
b.append(1)
return b
print a()
print a()
All of a sudden i got a list with 2 elems, but how? Shouldn't b be getting set to empty list every time.
Thanks for the help

Default arguments are only evaluated once, when the function is defined. It retains the same object from one invocation to the next, which means that the same list keeps getting appended to. Use a default value of None and check for that instead if you want to get around this.

Nothing to do with closures, at least not in the usual sense.
The default value for b is not "a new empty list"; it is "this particular object which I just created right now while defining the function, initializing it to be an empty list". Every time the function is called without an argument, the same object is used.

The corrected version, for the reasons given in other answers, is:
def a(b=None):
b = [] if b is None else b
b.append(1)
return b

default arguments are evaluated (once) when the function is defined, not each time it is called.
try this:
def a(b=None):
if b is None
b = []
b.append(1)
return b
print a()
print a()

Related

closure not correctly refering to correct variable

Here is a simple example showing a problem that I don't understand
callbacks = [lambda : 1, lambda : 2]
for i, c in enumerate(callbacks):
if i == 0:
cb1 = c
cb2 = lambda : c()
print(cb1()) # print 1
print(cb2()) # print 2
It seems that in cb1, I'm correctly able to copy the "correct" callback, ie the one I'm refering to in the loop iteration
However in cb2, even though I'm defining cb2 at a time when c refers to the 1st callback, it's updated afterwards to refer to the second callback
Can someone please shed some light on whatis going on ? this is pretty disconcerting
Is it possible that I write a lambda for cb2 and still refer to the first callback ?
This is expected behavior. To see why, consider the following example:
x = 1
def d():
return x
d() # returns 1
x = 2
d() # now returns 2
In the above example, the function d returns whatever value is assigned to the variable x at the time of execution. Variables in an enclosing scope are not copied in a function body, but referenced. The same is true if the variable holds a function value. Remember, functions are just values in Python. The behavior doesn't change just because you're using lambda syntax to define your functions.
The lambda is evaluated on runtime, when c already changed.
Try this instead:
cb2 = lambda c=c: c()
Using a default value, you can fixate a certain local variable.

Python interpreter sequence with a function [duplicate]

Suppose I have a Python function foo which takes a default argument, where that default is set to some global variable. If I now change that global variable before calling the function, the default argument is still set to the original value of that global variable.
For example:
x = 1
def foo(a=x):
print a
x = 2
foo()
This prints 1, instead of 2.
How should I be writing my code, so that I can change this global variable, and have it update this default argument?
A default variable is only evaluated and set once. So Python makes a copy of the reference and from then on, it always passes that reference as default value. No re-evaluation is done.
You can however solve this by using another object as default object, and then use an if statement to substitute it accordingly. Something like:
the_default = object()
x = 1
def foo(a = the_default):
if a is the_default:
a = x
print a
x = 2
foo()
Note that we use is to perform reference equality. So we check if it is indeed the default_object. You should not use the the_default object somewhere else in your code.
In many Python code, they use None as a default (and thus reduce the number of objects the construct). For instance:
def foo(a = None):
if a is None:
a = x
print a
Note however that if you do that, your program cannot make a distinction between a user calling foo() and foo(None) whereas using something as the_object makes it harder for a user to obtain a reference to that object. This can be useful if None would be a valid candidate as well: if you want foo(None) to print 'None' and not x.

How to make two functions share the same non global variable (Python)

Is there a way to make function B to be able to access a non global variable that was declared in only in function A, without return statements from function A.
As asked, the question:
Define two functions:
p: prints the value of a variable
q: increments the variable
such that
Initial value of the variable is 0. You can't define the variable in the global
enviroment.
Variable is not located in the global environment and the only way to change it is by invoking q().
The global enviroment should know only p() and q().
Tip: 1) In python, a function can return more than 1 value. 2) A function can be
assigned to a variable.
# Example:
>>> p()
0
>>> q()
>>> q()
>>> p()
2
The question says the global enviroment should know only p and q.
So, taking that literally, it could be done inline using a single function scope:
>>> p, q = (lambda x=[0]: (lambda: print(x[0]), lambda: x.__setitem__(0, x[0] + 1)))()
>>> p()
0
>>> q()
>>> q()
>>> p()
2
Using the tips provided as clues, it could be done something like this:
def make_p_and_q():
context = {'local_var': 0}
def p():
print('{}'.format(context['local_var']))
def q():
context['local_var'] += 1
return p, q
p, q = make_p_and_q()
p() # --> 0
q()
q()
p() # --> 2
The collection of things that functions can access is generally called its scope. One interpretation of your question is whether B can access a "local variable" of A; that is, one that is defined normally as
def A():
x = 1
The answer here is "not easily": Python lets you do a lot, but local variables are one of the things that are not meant to be accessed inside a function.
I suspect what your teacher is getting at is that A can modify things outside of its scope, in order to send information out without sending it through the return value. (Whether this is good coding practise is another matter.) For example, functions are themselves Python objects, and you can assign arbitrary properties to Python objects, so you can actually store values on the function object and read them from outside it.
def a():
a.key = "value"
a()
print a.key
Introspection and hacking with function objects
In fact, you can sort of get at the constant values defined in A by looking at the compiled Python object generated when you define a function. For example, in the example above, "value" is a constant, and constants are stored on the code object:
In [9]: a.func_code.co_consts
Out[9]: (None, 'value')
This is probably not what you meant.
Firstly, it's bad practise to do so. Such variables make debugging difficult and are easy to lose track of, especially in complex code.
Having said that, you can accomplish what you want by declaring a variable as global:
def funcA():
global foo
foo = 3
def funcB():
print foo # output is 3
That's one weird homework assignment; especially the tips make me suspect that you've misunderstood or left out something.
Anyway, here's a simpler solution than the accepted answer: Since calls to q increment the value of the variable, it must be a persistent ("static") variable of some sort. Store it somewhere other than the global namespace, and tell p about it. The obvious place to store it is as an attribute of q:
def q():
q.x += 1
q.x = 0 # Initialize
def p():
print(q.x)

Python printing a procedure

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))

classes and strings in definitions in python

class someDistance(Distance):
def __init__(self, dist_funct_name_str = 'Something Distance', p=2):
self.p = p
Just wanted to ask what the
dist_funct_name_str = 'Something Distance'
does in the definition?
Any help would be greatly appreciated!
It is used to define the default value of the variable dist_funct_name_strin case when no value is passed for it when the object someDistance was invoked.
example:
In [69]: def func(a,b=2): # b has default value of 2
....: print a,b
....:
....:
In [70]: func(1) # no value passed for b ,so it is equal to 2
1 2
In [71]: func(1,5) # 5 is passed for b, so b=2 is neglected
1 5
Both dist_funct_name_str and p are called default values. If these values aren't set when __init__ is called, then these default values are used instead.
They also occur on other functions as well - not just __init__.
dist_funct_name_str = 'Something Distance'
Is a "default parameter" passed to the init function. It's basically the parameter used by default of a user or coder has not passed any arguments to a function.
You can read up a bit more on this here: http://effbot.org/zone/default-values.htm and I also recommend this: http://www.deadlybloodyserious.com/2008/05/default-argument-blunders/ .
I've run into the same thing not long ago.

Categories