Metaclass insanity - another use case

I was reading the "metaclass insanity" thread this morning about dotted __name__ for nested classes, and I thought I should chime in that I've actually *used* this technique. That is, I've had classes of the form: class outer: class inner: ... And then regenerated 'inner' such that inner.__name__ == 'outer.inner' and stored it in globals()['outer.inner']. This *does* work with existing pickle code; in fact it worked as far back as Python 1.5.2! As for *why* I had inner classes, the following might be a good example: class ModelElement(Element): class isSpecification(model.Field): isRequired = 1 qualifiedName = 'Foundation.Core.ModelElement.isSpecification' _XMINames = ('Foundation.Core.ModelElement.isSpecification',) name = 'isSpecification' referencedType = 'Boolean' class stereotype(model.Reference): isNavigable = 0 isRequired = 1 _XMINames = ('Foundation.Core.ModelElement.stereotype',) name = 'stereotype' referencedType = 'Stereotype' refTypeQN = 'Foundation.Core.ModelElement.stereotype' referencedEnd = 'extendedElements' This is a tiny excerpt from some automatically generated code which defines the UML 1.3 metamodel as a set of Python classes. The nested classes represent structural features of the defined outer class, and enforce properties such as multiplicity, requiredness, etc., as you can see. In an earlier version of this work, the inner classes had metaclasses whose __get__ method instantiated the inner class, and placed an instance in the outer object instance. That is, each ModelElement instance would have a 'stereotype' instance created on demand, which would manage the 'stereotype' property. And for this to be picklable, it was necessary for the inner classes to be accessible by the pickle machinery -- hence my use of qualified class names, as described above. I will admit that I no longer use this approach for the inner classes; I found a way to get by without ever instantiating them. The above code is still valid, but the metaclasses used are different. So the pickling is simpler and faster. I'm not sure if this is really an argument for or against, but at least it's actual usage. :)

OK. Setting __name__ to 'outer.inner' seems to be the best solution, so I'll add that to my TODO list. [SF bug #633930]
And I think there's nothing wrong with it -- it's a different use of classes, but makes sense; it's a good use of nested namespaces (as opposed to nesting helper classes inside the main class which they help). --Guido van Rossum (home page: http://www.python.org/~guido/)

"Phillip J. Eby" <pje@telecommunity.com>:
I'm not sure if it would be quite what Phillip needs, but I've been wondering recently whether Python could benefit from having an "instance" statement which does for instances what the "class" statement does for classes. The idea is you'd be able to say something like instance isSpecification(model.Field): isRequired = 1 qualifiedName = 'Foundation.Core.ModelElement.isSpecification' and it would be equivalent to isSpecification = model.Field(isRequired = 1, qualifiedName = 'Foundation.Core.ModelElement.isSpecification') One of the use cases I have in mind is GUI programming, where you frequently need to build complicated nested structures with lots of keyword arguments to constructors. A construct like this might help you to lay out the code more neatly and readably. I haven't really thought through the details properly, though. Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg@cosc.canterbury.ac.nz +--------------------------------------+

On Wed, Nov 06, 2002, Greg Ewing wrote:
Yeah, but that doesn't gain you all that much over isSpecification = model.Field( isRequired = 1, qualifiedName = 'Foundation.Core.ModelElement.isSpecification' ) -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ Project Vote Smart: http://www.vote-smart.org/

OK. Setting __name__ to 'outer.inner' seems to be the best solution, so I'll add that to my TODO list. [SF bug #633930]
And I think there's nothing wrong with it -- it's a different use of classes, but makes sense; it's a good use of nested namespaces (as opposed to nesting helper classes inside the main class which they help). --Guido van Rossum (home page: http://www.python.org/~guido/)

"Phillip J. Eby" <pje@telecommunity.com>:
I'm not sure if it would be quite what Phillip needs, but I've been wondering recently whether Python could benefit from having an "instance" statement which does for instances what the "class" statement does for classes. The idea is you'd be able to say something like instance isSpecification(model.Field): isRequired = 1 qualifiedName = 'Foundation.Core.ModelElement.isSpecification' and it would be equivalent to isSpecification = model.Field(isRequired = 1, qualifiedName = 'Foundation.Core.ModelElement.isSpecification') One of the use cases I have in mind is GUI programming, where you frequently need to build complicated nested structures with lots of keyword arguments to constructors. A construct like this might help you to lay out the code more neatly and readably. I haven't really thought through the details properly, though. Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg@cosc.canterbury.ac.nz +--------------------------------------+

On Wed, Nov 06, 2002, Greg Ewing wrote:
Yeah, but that doesn't gain you all that much over isSpecification = model.Field( isRequired = 1, qualifiedName = 'Foundation.Core.ModelElement.isSpecification' ) -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ Project Vote Smart: http://www.vote-smart.org/
participants (4)
-
Aahz
-
Greg Ewing
-
Guido van Rossum
-
Phillip J. Eby