Convention for declaring variables in Python, when required for scope? - python

Take this example:
def f():
myvar = None
def g():
print myvar
...
myvar = get_real_value()
g()
Is "myvar = None" a conventional (or at least, reasonable) way of declaring the variable, to make it visible to g()? Is there a better way? (Python 2.6.x, if relevant)

There is no need to declare the variable before the definition for g():
>>> def f():
... def g():
... print myvar
... myvar = 1
... g()
...
>>> f()
1
However, if you can avoid referencing non-local variables in g() that would be preferable, which you would probably do here by having myvar be a parameter to g().

You don't need to pre-initialize the variable; it only has to be initialized before you call g(). Just remove the myvar = None line.
For clarity, I prefer to move local functions as close to their point of invocation as practicable, so that the initialisation of local variables that a function uses comes before the function itself.

Related

Would scope would this variable(s) belong to?

class Something:
x = "hi"
def func(self):
k = "hi2"
In this piece of code, x as a class attribute and k as a variable. What scope (local, enclosed, global, builtin) would x belong to and what scope would k belong to?
You say you don't want an answer like "in the scope of the function" or "-- the class", but that would be the most precise answer. A scope like local is always relative to where you are.
If you are in the global scope, then only the class itself is in both the local and global scope (which are the same then), but neither of the variables are. You can access x via the class, but k will only be defined when the function is called.
If you are inside of func, then k and self are in the local scope, but x is in neither the local nor global scope. It is not in the enclosed scope either; it can not be accessed directly, as in print(x), but only via the instance self or the class Something.
class Something:
x = "hi"
def func(self):
k = "hi2"
print(locals()) # contains k, self
print(globals()) # contains Something
print(k) # works
print(self.x) # works
print(Something.x) # works
print(x) # does not work
Something().func()
The case is different with nested functions. Here, variables defined in the outer functions are in the "enclosing scope", but may be promoted to the local scope by using them:
def f():
a = []
def g():
b = None
# a = [] # define a new a in local scope?
# a.append(42) # without above line, this changes enclosed a
print(locals()) # only b, unless you use a here
g()
print(a)
f()
if you leave the commented lines as they are, only b in in the inner local scope
if you activate the append line, a from the enclosing scope is moved to the local scope and changed in both scopes
if you activate both commented lines, a new a is defined in the local scope without changing the a in the enclosing scope

How to use nonlocal statement with several inner functions?

Might someone explain me why this function is not working ? Shouldn't the "nonlocal" statement makes x understandable in g, and therefore in h ?
def f():
def g():
nonlocal x
x= 1
def h():
print(x)
>>> SyntaxError: no binding for nonlocal 'x' found
Edit : I used nonlocal in order not to define x anywhere else than in g() : I have to define several variables in my code, and want to do it in a function init_var(). For lisibility, I want to avoid declaring them in my main function. Is there a way to adapt the previous code for this aim ?
From docs:
Names listed in a nonlocal statement, unlike those listed in a global statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot be determined unambiguously).
Your x is not pre-existing at the point of nonlocal. Try x = None just before def g(): to create a binding for nonlocal to refer to.
The ambiguity problem stated by the docs are easy to see here:
def f():
def g():
def h():
def i():
def j():
nonlocal x
Which functions should have access to x, and which shouldn't? On the other hand, here it is clear:
def f():
def g():
def h():
x = None
def i():
def j():
nonlocal x
In this case, f and g don't know x, while h, i and j do.
Not sure whether what you are trying really helps readability. If you want to to structure your code, you might want to consider using a class and (instance) attributes. That being said, if you want to avoid multiple assignment lines, you can use attributes of the outer function:
>>> def f():
... def g():
... f.a = 5
... def h():
... print(f.a)
... g()
... h()
...
>>> f()
5

Using global variables in python in a function

def foo():
global a
a = 10
vs
a = 0
def foo():
a = 10
What is the use of declaring global in a function instead of declaring variables right at the top. It should be cleaner this way ?
Q. What is the use of declaring global in a function instead of declaring variables right at the top?
Generally we define few regularly used constants as global variables.
>>> import math
>>> math.pi
3.141592653589793
Mathematical contants/Web Page/Servernames/URLs - which wont change over a period of time.
In general, it is not recommended to RE-DEFINE global variable or define global variables with in a function. But few exception cases are there where we are left with no option but to re-define it. Could be due to a new upgrade in old system where this variable is heavily used across.
So please go with your second approach. Define 'a' outside your
function. This also looks good & easy to read.
>>> a = 10
>>> def foo():
... a = 14 # defining a local variable called a
...
>>> a
10
>>>
>>> foo()
>>> a
10
>>> # a = 14 has no scope outside foo function
>>>
>>> def foo():
... global a # notify function to use global variable here.
... a = 15 # re-defining global ==> nt preferred it
...
>>> a
10
>>> foo()
>>> a # see now it changed here.
15
Hope this helps.
In the first case the value remains same in all the functions.
def set_globvar_to_one():
global globvar
globvar = 1
print globvar
def print_globvar():
print globvar # No need for global declaration to read value of globvar
set_globvar_to_one()
print_globvar()
The output will be 1 and 1.
But 2nd case
def set_globvar_to_one():
globvar = 1
print globvar
def print_globvar():
print globvar # No need for global declaration to read value of globvar
set_globvar_to_one()
print_globvar()
Here you get error saying globvar is not defiend, coz there is no local or global variable named globavar
That would make it ambiguous. Look at this,
a = 0
def foo():
a = 10 # *
Look at the line marked *. Are you assigning to the global a or is this a local variable a with a value 10. The interpreter has no way to knowing what you meant. Thus, the need for global.
a = 0
def foo():
a = 10 # local variable a
def bar():
global a # will be modifying global variable a in this function
a = 10 # assign 10 to global variable
In your first example "a" is not available before foo() is called. Once it is defined in the function it available outside of the function.
In the second example it is available before foo() is called butchanges to it inside the function do not affect the global version .
This example should demonstrate the difference between the two examples
#!/usr/bin/python
def foo():
global a
a = 10
print a
try:
print a
except Exception,e:
print e
foo()
print a
print "-"*70
b = 0
def bar():
b = 10
print b
print b
bar()
print b
Output:
global name 'a' is not defined
10
10
----------------------------------------------------------------------
0
10
0
If you declare it as a global, you don't have to return it.
If you don't use global, you have the function to return a.
Without global it be like this:
In [7]: def foo():
...: a = 10
...: return a
...:
In [9]: a = foo()
In [10]: a
Out[10]: 10
With global:
In [11]: a = 0
In [12]: def foo2():
....: global a
....: a = 10
....:
In [13]: a
Out[13]: 0
In [14]: foo2()
In [15]: a
Out[15]: 10
It is you who decide if you want your function to return or to use global.
It can simplify you code, it can be useful for function that calculates some constants that you don't want to call it each time.
But if use it for single procedure, prefer "return" method.
if you are using the same variable inside the loop then there will be a competition between the global and local variable . so if you want to use the value of the global variable in the loop you have to mention the 'global' keyword

Getting the value of a local variable in another function

I'm tinkering around with Python. I have two functions. The first one calls the second, and from the second I am trying to get the value of a local variable within the first, like so:
def b():
local_var = 8
a()
def a():
#get b::local_var here?
I understand that it is possible in python to print out the stack, but I was wondering about accessing the variables and memory within those functions.
Is this even possible?
yes you can, just pass the variable in the function
def b():
local_var = 8
a(local_var) #1
def a(LV): #2
print LV
1
you passed the variable
2
created a new variable LV and assigned the local_var value to LV
Variables that are defined inside a function body have a local scope, and those defined outside have a global scope.
This means that local variables can be accessed only inside the function in which they are declared, whereas global variables can be accessed throughout the program body by all functions. When you call a function, the variables declared inside it are brought into scope.
So in this case you can use 2 way :
1. define a global variable :
>>> def b():
... global local_var
... local_var=8
... a()
...
>>> def a():
... print local_var
...
>>> a
8
2.pass the variable in a() as its argument :
>>> def b():
... local_var=8
... a(local_var)
...
>>> def a(arg):
... print arg
...
>>> a
8

Python closures and variable lookup

The following code works as intended:
def f():
def g():
print(a)
a = 42
return g
f()()
g loads a from its closure and all is well.
Now this snippet fails horribly with UnboundLocalError.
def f():
def g():
print(a)
a = 43
a = 42
return g
f()()
Looking at the dis, the first code calls LOAD_CLOSURE and the second does not. Taking this into consideration it is obvious why the error is raised. The question however is this:
How does python know when to draw a variable from the closure or from the local scope? (Considering that print(a) precedes a = 43.)
Is this decision taken at compile time? (Well, looks like it, considering that print(a) precedes a = 43)
This post is not about the nonlocal or global keywords.
In the absence of nonlocal or global declarations, Python decides whether a variable is local at bytecode compilation time by checking the function for assignments to the variable. Since the second example assigns to a in g, a is local to g in that version.

Categories