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?
CodePudding user response:
class Something:
x = "hi" # this is enclosed
def func(self):
k = "hi2" # this is local
print(x) #returns a NameError
print(Something.x)
print(k) #returns a NameError
print(Something.func('k')) #returns None because there is no print(k)
If you want to access k:
class Something:
x = "hi"
def func():
Something.func.k = "hi2"
Something.func()
print(Something.func.k)
CodePudding user response:
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 thea
in the enclosing scope