> Guido van Rossum wrote: > > > Looks like you are missing the point. Of course I want to keep the > > class as a local scope *inside the class def*. John Max Skaller replied: > Ah, ok: seem's I was missing your intent. > > > But I need it out of the way when executing methods. > > I don't think this is the right idea. Consider: > > class X: > x = 'x' > def f(self): print x > a = X() > a.f() # should print 'x' We understand each other perfectly. I just disagree with you on what this example should do! I believe that in the sake of backwards compatibility *as well as* not "giving in" to Java and C++ conventions that I believe are a bad idea for Python, the reference to 'x' from inside 'f' should not find the class variable 'x' but only a module-global 'x'. Backwards compatibility: currently this program prints '1': x = 1 class C: x = 2 def f(self): print x C().f() I believe it should not be broken; I expect that this is, for better or for worse, a popular idiom, especially when you look at methods rather than varibles. I believe it might be common to find this: from lower_level_module import some_call class C: def some_call(self): "OO wrapper around some_call()" return some_call(self.data) Your rule would break this, because the reference to some_call() inside C.some_call() would be changed to make a (senseless, recursive) reference to itself instead of to the globally imported some_call() function. Java/C++ expectations: in Java/C++, the rules are different. Inside a method, not just names defined in the current class are in scope, but also all names defined in its base classes. Look at this: # Module a.py class B: def f(self): pass # Module b.py import a class C(a.B): def g(self): pass def h(self): g(self) f(self) Under your rules, the reference to g() in h() would work, but the reference to f() would fail. In similarly structured Java or C++ code, h() could reference both g() and f() without a naming disambiguation. Python requires that you specify the class when you reference a class attribute (method or class variable). I don't want to lose this rule, it is important (to me) for readability. [...more examples elided...] > The point is that I think there is not really much choice > in the matter: when you lookup an unqualified name in a function, > you must look in the function locals, then in the scope of the > object in which the function is defined, and then in the scope > in which that is defined .. and so ontil you reach the bottom > of the stack (which presumably is 'builtins'). I claim different, and above I have explained why I think this is necessary. I'd agree if you said "the scope of the *function* in which it is defined." > There's no real issue of keeping the class of the object > of a bound method 'out of the way' when executing the function > of the bound method. The scope of that class should be searched > if, and only if, the function happens to have been defined > inside that class. Note there is no such thing as a method > in python: executing a bound (or unbound) method results > in executing a plain old function. If the code generator keeps track of the distinction between class and function scopes, my rules can be implemented easily without introducing a distinction between functions and methods. > You _could_ exclude class scopes from the search stack > associated with a function, and just search locals, then > enclosing functions, then the enclosing module and finally > builtins. But it would be highly inconsistent, and not what > people used to lexical scoping would expect. Yet, this is what I want. It's impossible to design things so that people coming from very different backgrounds will never encounter a surprise. Since Python is primarily an OO language, and there's ten years of established Python rules, I prefer to give the OO people and existing Python users an easier time (note that the OO people at least can count on *consistently* not seeing the class scope in the "methods") and tell the lexical-scoping people about the exceptions. > It will be hard > enough to explain the _consistent_ rule that only local > bindings can be changed by assignments -- unless a global > directive changes that. But that rule IS consistent (and the > global directive much less so!) > I think there is general agreement that lexically > scoping functions inside functions will not break much code. > Do you have an example of real application code where searching a class > in which a function is defined will break code? I haven't found one yet, but I've seen plenty of examples where a class defines a method with the same name as a global function (including lots in the standard library -- it really is a common idiom). I think this comes too close to risk breakage. But even if we find that this doesn't break anything, I still think it's unwise to allow unqualified access to class attributes from within methods. People would discover that in this example: class C: def m1(self): pass def m2a(self): m1(self) def m2b(self): self.m1() m2a() and m2b() would be equivalent, i.e. m1(self) and self.m1() are equivalent. That's evil, because it opens up a meaningless choice between alternative (and the m1(self) notation is inferior, because it doesn't look in base classes). But I'm beginning to repeat myself, so I think I've said all that can be said about this. Sorry the scope rules in Vyper are wrong. --Guido van Rossum (home page: http://www.python.org/~guido/)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4