classification
Title: Assigning function parameter to class attribute by the same name
Type: behavior Stage:
Components: Interpreter Core Versions: Python 3.10, Python 3.9
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: eric.smith, jennydaman, steven.daprano
Priority: normal Keywords:

Created on 2021-03-03 00:36 by jennydaman, last changed 2021-03-03 09:19 by steven.daprano.

Messages (6)
msg387987 - (view) Author: (jennydaman) Date: 2021-03-03 00:36
# Example

Consider these three examples, which are theoretically identical

```
a = 4

class A:
    a = a

print(A.a)

def createB(b):
    class B:
        z = b
    print(B.z)
    
createB(5)

def createD(D):
    class D:
        d = d
    print(D.d)
    
createD(6)
```

## Expected Output

```
4
5
6
```

## Actual Output

```
4
5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in createD
  File "<stdin>", line 3, in D
NameError: name 'd' is not defined
```
msg387990 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-03-03 01:21
Was 
def createD(D):

supposed to be:
def createD(d):

?

Not that that changes your problem. I just want to understand the exact issue.
msg387991 - (view) Author: (jennydaman) Date: 2021-03-03 01:22
# Example

Consider these three examples, which are theoretically identical

```
a = 4

class A:
    a = a

print(A.a)

def createB(b):
    class B:
        z = b
    print(B.z)
    
createB(5)

def createD(d):
    class D:
        d = d
    print(D.d)
    
createD(6)
```

## Expected Output

```
4
5
6
```

## Actual Output

```
4
5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in createD
  File "<stdin>", line 3, in D
NameError: name 'd' is not defined
```
msg387992 - (view) Author: (jennydaman) Date: 2021-03-03 01:23
Yes sorry that was a typo
msg388005 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-03-03 08:55
Here's an example that shows what is going on:


def demo():
    a = 1
    class B:
        x = a
    print(B.x)  # Okay.
    
    class C:
        x = a  # Fails.
        if False:
            a = None
    print(C.x)


If you run that, B.x is printed (1) but assigning to C.x fails:

>>> demo()
1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in demo
  File "<stdin>", line 8, in C
NameError: name 'a' is not defined


The reason is that inside a function, assignment to a name makes it a local. This interacts oddly with class scope.

By the way, I get the same results with this all the way back to Python 2.4. (I don't have older versions to test.) So this has existed for a very long time.
msg388008 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-03-03 09:19
Looking at the disassembly of the demo() function also shows differences between the B and C classes.

I seem to recall discussion about this on, maybe, the Python-Dev list. I think resolving this will probably have to wait on a re-design of the exact scoping rules with respect to classes inside functions.
History
Date User Action Args
2021-03-03 09:19:41steven.dapranosetmessages: + msg388008
2021-03-03 08:55:52steven.dapranosetnosy: + steven.daprano
messages: + msg388005
2021-03-03 01:23:09jennydamansetmessages: + msg387992
2021-03-03 01:22:53jennydamansetmessages: + msg387991
2021-03-03 01:21:09eric.smithsetnosy: + eric.smith
messages: + msg387990
2021-03-03 00:36:29jennydamancreate