
On Sun, Aug 7, 2011 at 10:10 PM, Guido van Rossum <guido@python.org> wrote:
On the rest of that rejected PEP:
- I'm not actually sure how easy it is to implement the setting of __function__ when the frame is created. IIRC the frame creation is rather far removed from the function object, as there are various cases where there is no function object (class bodies, module-level code) and in other cases the function is called via a bound method. Someone should write a working patch to figure out if this is a problem in practice.
With a PEP 3135 closure style solution, the cell reference would be filled in at function definition time, so that part shouldn't be an issue.
- The primary use case for __function__ to me seems to access function attributes, but I'm not sure what's wrong with referencing these via the function name. Maybe it's when there's a method involved, since then you'd have to write <classname>.<methodname>.<attrname>.
That does raise an interesting question, though: in a function wrapped via decorators, should __function__ refer to the innermost function or the outermost one? Reference by name lazily accesses the outermost one, but doesn't care how the decorators are applied (i.e. as part of the def statement or via post decoration). A __class__ style cell reference to the result of the 'def' statement would behave differently in the post decoration case. While referencing the innermost function would likely be wrong in any case involving function attributes, having the function in a valid state during decoration will likely mandate filling in the cell reference before invoking any decorators. Perhaps the best solution would be to syntactically reference the innermost function, but provide a clean way in functools to shift the cell reference to a different function (with functools.wraps doing that automatically). This does seem like an area ripe for subtle decoration related bugs though, especially by contrast with lazy name based lookup.
- It seems that the "current class" question has already been solved for super(). If more is needed I'd be okay with extending the machinery used by super() so that you can access the magic "current class" variable explicitly too.
No need to extend it, that info is already available for explicit reference:
class C: ... def f(self): ... print(__class__) ... C().f() <class '__main__.C'>
(see postscript for more details)
- For "current module" I've encountered a number of use cases, mostly having to do with wanting to define new names dynamically. Somehow I have found:
globals()[x] = y # Note that x is a variable, not a literal
cumbersome; I'd rather write:
setattr(__this_module__, x, y)
There are IIRC also some use cases where an API expects a module object (or at least something whose attributes it can set and/or get) and passing the current module is clumsy:
foo(sys.modules[__name__])
While this may sound a little hypocritical coming from the author of PEPs 366 and 395, I'm wary of adding new implicit module globals for problems with relatively simple and robust alternatives. In this case, it's fairly easy to get access to the current module using the idiom Guido quoted: import sys _this = sys.modules[__name__] (or using dict-style access on globals()) Cheers, Nick. P.S. More details on the magic __class__ closure reference:
dis.show_code(C.f) Name: f Filename: <stdin> Argument count: 1 Kw-only arguments: 0 Number of locals: 1 Stack size: 2 Flags: OPTIMIZED, NEWLOCALS Constants: 0: None Names: 0: print Variable names: 0: self Free variables: 0: __class__ C.f.__closure__[0].cell_contents <class '__main__.C'>
-- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia