On 25/02/2019 21.15, Chris Angelico wrote: > On Tue, Feb 26, 2019 at 6:58 AM DL Neil <pythonl...@danceswithmice.info> > wrote: >> >> On 26/02/19 5:25 AM, ast wrote: >>> I noticed a quirk difference between classes and functions >>> >>> x=0 >>> >>> class Test: >>> x = x+1 >>> print(x) >>> x = x+1 >>> print(x) >> ... >> >>> Previous code doesn't generate any errors. >>> x at the right of = in first "x = x+1" line is >>> the global one (x=0), then x becomes local >>> within a function, this is not allowed >>> >>> x = 0 >>> >>> def f(): >>> x = x+1 >>> >>> f() >>> UnboundLocalError: local variable 'x' referenced before assignment >>> Since x is written inside the function, it is considered as a local >>> variable and x in x+1 is undefined so this throw an exception >>> Any comment ? >> >> >> At first I misunderstood the question, and even now I'm slightly mystified:- >> >> Is the observation to do with the principles of "closure" (being applied >> to the function) compared with the differences between class and >> instance variables? > > Classes and functions behave differently. Inside a function, a name is > local if it's ever assigned to; but in a class, this is not the case. > (Honestly, I'm not sure why this is, but it's hardly ever significant; > metaprogramming seldom runs into this kind of thing.)
I imagine there's a justification for the difference in behaviour to do with the fact that the body of a class is only ever executed once, while the body of a function is executed multiple times. But I don't quite see it. > >> A question from me: (I'm not an O-O 'native' having taken to it long >> after first learning 'programming') I've used class attributes to hold >> 'constants', eg >> >> MAXIMUM_WEIGHT = 100 >> >> Thus only an assignment to which reference/assertions will be made 'later'. >> >> I have initialised a counter to zero and then incremented within the >> instantiated object's __init__(), ie keeping track of how many of 'these >> objects' have been instantiated. > > Once you're inside a method, you would reference it with a dot - > either "self.MAXIMUM_WEIGHT" or "cls.MAXIMUM_WEIGHT". So it's now an > attribute, not a local name. > >> So, I can imagine taking a value from outside the class' namespace, >> modifying it in some way (per the first "x = x+1") and then retaining >> the result as a class attribute (a calculation performed once - when the >> class code is compiled). > > Yes, this is perfectly legitimate. Not common but legit. > >> However, (after that first calculation/definition of the class >> attribute) why would one (normally) want to redefine the same class >> attribute (the second x = x+1), at the 'class level'? >> (perhaps just done for its amusement value?) > > That would not be common either. If you're redefining a variable > multiple times within a class block, you probably don't also have it > at top level. (For instance, you can put a "for" loop inside a class > statement to create attributes/methods, but the loop variable is > unlikely to also be a global.) > > But hey! It's fun! :) > > ChrisA > -- https://mail.python.org/mailman/listinfo/python-list