Home > Software design >  Would scope would this variable(s) belong to?
Would scope would this variable(s) belong to?

Time:08-11

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 the a in the enclosing scope
  • Related