0

I may sometimes make confusion with terminology, but I think I know python namespace and scope rules, and the use of the global keyword. I know that from a local scope (inside a function for example) I can access the global scope in read-only mode, unless a variable is declared global.

But I found something a bit strange to me when classes come in play. I hope this example is clear enough:

class Bar:
    def __init__(self, x):
        self.x = x

barob = Bar(6)

def foobar():
    barob = Bar(3) #local scope, the barob in global namespace is not affected.

foobar()
print(barob.x) #prints 6

def foobar2():
    global barob #barob is the one in global space
    barob = Bar(3)

foobar2()
print(barob.x) #prints 3

Up to now everything is clear to me. But if I do:

barob = Bar(5)
def foobar3():
    barob.x = 7

foobar3()
print(barob.x) #prints 7. Why?

So my question is: why is permitted to reassign the x attribute of barob in global namespace from the local scope of foobar3()?
I would have expected an UnboundLocalError raised, or some other kind of complain from the interpreter, as I am writing to a variable (well, an attribute of an object in this case) in the global namespace.
The best of my understanding is that when coming to scope, attributes are treated differently from variables, but I don't understand why.

If relevant, I am using python3.6.7, but I tried with python2.7 too, same behaviour.

0

1 Answer 1

4

In foobar3() you are assigning the x property of the global barob variable. You are not making a declaration. Python cannot define a variable with barob.x because it needs an existing instance for barob to figure out where to place the value of x. So it is first looking for the instance (and finding the global one) instead of declaring a variable.

It would have been different if you had first allowed Python to declare a barob variable and then assigned it:

barob = Bar(5)
def foobar3():
    barob   = Bar(0)
    barob.x = 7
Sign up to request clarification or add additional context in comments.

1 Comment

So I was wrong to consider that also barob attributes should have been read-only from foobar3() being barob in the global space. Thanks for the explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.