metaclass and customization with parameters

Robert Brewer fumanchu at amor.org
Wed Oct 6 11:27:06 EDT 2004


Alex Martelli wrote:
> Gustavo Niemeyer <niemeyer at conectiva.com> wrote:
>    ...
> > > >>> class MyClass:
> > > ...         for i in range(10):
> > > ...                 def newmethod(self,i=i):
> > > ...                         print "I'm method #%d" % i
> > > ...                 newname = "method%d" % i
> > > ...                 locals()[newname] = newmethod
>    ...
> > As an interesting side effect, the class above will have
> > 'newname', 'newmethod', and 'i' attributes, besides 'method0-9'.
> 
> ...which incidentally shows that i is a +local+ variable...
> 
> > Of course, in your example, not using the 'i=i' trick would be a
> > problem, since the 'i' variable is lost, and inside the method a
> > global is looked for, creating an error.
> 
> True, the opcode for i is indeed a LOAD_GLOBAL.  Why _that_ should be
> the case is anything but an 'of course' to _me_, though, as we just
> showed that i is a +local+.  newmethod is not seen as a 
> nested function
> of the anonymous function built from the codeobject's that's the
> classbody.  I _think_ there's some adhoccery in the Python 
> compiler (not
> the easiest part of Python to read and understand, so I apologize for
> any potential confusion here) to specifically ensure that -- I guess
> it's for backwards compatibility with old Python versions which didn't
> have nested scopes, otherwise any barename in a method would 
> refer first
> to the classbody (acting as its 'outer function') which could shadow
> globals.  A bit confusing for an "of course", nevertheless;-).

Hmmm. I would have guessed that i isn't available to the class until the
class statement is finished executing; that is, when newmethod is
defined, there is not yet any MyClass class object in which to look up
i. Therefore, newmethod uses LOAD_GLOBAL. But I'm just guessing.


Robert Brewer
MIS
Amor Ministries
fumanchu at amor.org



More information about the Python-list mailing list