At 12:38 PM 12/16/2006 -0800, Talin wrote: >Phillip J. Eby wrote: >>At 11:30 AM 12/16/2006 -0800, Talin wrote: >>>The general idea is to have the metaclass create a mapping object which >>>is used as the 'locals' dictionary for the suite following the class >>>statement. There would be some special-named function of the metaclass, >>>such as '__metadict__', which would construct a new mapping object. I >>>haven't seen many alternative proposals to this. >>There's mine, where you simply create mcls(name, bases, {}) and then map >>locals operations to get/set/delattr operations on the class. This would >>presumably be done using a simple mapping proxy, but it would be a >>built-in type rather than the user having to implement their own mapping type. > >I'm not sure I entirely understand this. I did think about the idea of >defining special get/set methods on the class, but everything I came up >with was more complicated than just creating a special locals dict.
My proposal uses a special locals dict, but it's a single standard builtin one that looks like this: class Metadict: def __init__(self, cls): self.cls = cls def __getitem__(self, key): return getattr(self.cls, key) def __setitem__(self, key, value): setattr(self.cls, key, value) def __delitem__(self, key): delattr(self.cls, key) so, the class creation process is: cls = mcls(name, bases, {}) exec suite in Metadict(cls), globals() The idea is to avoid creating some new special-purpose mechanism for this, when we already have an existing one that would work nicely, given a suitable Metadict implementation. Any get/set/delitem operations on the metadict map directly to get/set/delattr operations on the metaclass instance. >The main issue for me is that I think that its important to distinguish >between get/set operations that are done at class definition time, and >get/set operations that are done later, after the class is created. Well, we could always treat the class as a context manager, and allow the metaclass to have __enter__/__exit__ methods. e.g.: cls = mcls(name, bases, {}) if hasattr(cls,'__enter__'): with cls: exec suite in Metadict(cls), globals() else: exec suite in Metadict(cls), globals() Unfortunately, this just highlights the attribute ambiguity problem where a class's attributes may be either provided by a metaclass, or be intended for the class' instances. A class could have an __enter__ because it's inheriting it from its base class. So, I suppose you would really need to check whether mcls has __enter__, but even then, you won't *execute* that __enter__ in the with: block, because an inherited __enter__ can override it. (It'd be really nice if there was a way to generally fix this ambiguity in Py3K, as it's a problem for any method that could be on either a class or an instance, but isn't implemented via a C-level slot. But that's probably another thread altogether.) _______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com