0
$ cat func.py 
a = 'global'
def myfunc():
  a = 'myfunc'
  class myclass:
    print('myclass a =', a)
#    a = 'myclass'
myfunc()
$ python3.8 func.py 
myclass a = myfunc

$ cat func.py 
a = 'global'
def myfunc():
  a = 'myfunc'
  class myclass:
    print('myclass a =', a)
    a = 'myclass'
myfunc()
$ python3.8 func.py 
myclass a = global

Which are the variable visibility rules applicable to the a attribute of myclass and how do they explain these results? References to documentation welcome, but not required.

I have been asked to explain how does Short description of the scoping rules? not answer my question here. The answer is ridiculously simple: that question and its answers do not address the case of a nested class, with one exception, which certainly does not explain the weird "global" output in my example, which directly contradicts the rule that the variable should be resolved to the closest nesting scope.

Doru Georgescu
  • 309
  • 2
  • 12
  • 1
    if you put a class in a function it works as a decorator – Flow Oct 15 '22 at 14:09
  • 2
    Does this answer your question? [Short description of the scoping rules?](https://stackoverflow.com/questions/291978/short-description-of-the-scoping-rules) – buran Oct 15 '22 at 14:12
  • 1
    There is no `a` attribute of `myclass`. It is a closure variable. – mousetail Oct 15 '22 at 14:19
  • @mousetail I believe that classes cannot define closures. Your comment was helpful because it made me read about closures. – Doru Georgescu Oct 20 '22 at 19:11
  • @Flow Decorators are based on closures, and I believe that classes do not define closures. Your comment was helpful because it made me read about decorators. – Doru Georgescu Oct 20 '22 at 19:12
  • @buran Your link is very helpful. It is the first coherent presentation on the topic that I found. However, classes are not clearly addressed. I believe that classes have not been designed for this scope imbrication. – Doru Georgescu Oct 20 '22 at 19:24
  • @DoruGeorgescu Happy to help, I do not know that as well so thanks for informing me – Flow Oct 20 '22 at 21:45
  • @DoruGeorgescu Classes can define closures themselves. In fact classes are really just a type of closure. – mousetail Oct 21 '22 at 06:07
  • @mousetail Function attributes can define closures because they are functions. If you can provide an example where classes themselves define closures, I'd be most interested to see it. – Doru Georgescu Oct 21 '22 at 07:27

1 Answers1

0

4.2.2. Resolution of names

Class definition blocks and arguments to exec() and eval() are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace.

In the first example, a follows the normal rules for name resolution and resolves to the nearest enclosing scope, which is myfunc().

In the second example, a is local, because it is assigned within the class scope with no nonlocal or global declaration, and it is unbound because it is resolved before the assignment. So it resolves to the global scope.

This is weird.

Doru Georgescu
  • 309
  • 2
  • 12