[me] > > The best rule I can think of so far is that DictType.__dict__ gives > > the *true* set of attribute descriptors for dictionary objects, and is > > thus similar to Smalltalks's class.methodDict that Jim describes > > below. DictType.foo is a shortcut that can resolve to either > > DictType.__dict__['foo'] or to an attribute (maybe a method) of > > DictType described in TypeType.__dict__['foo'], whichever is defined. > > If both are defined, I propose the following, clumsy but backwards > > compatible rule: if DictType.__dict__['foo'] describes a method, it > > wins. Otherwise, TypeType.__dict__['foo'] wins. [MAL] > I'm not sure I can follow you here: DictType.__repr__ is the > representation method of the dictionary and not inherited > from TypeType, so there should be no problem. The problem is that both a dictionary object (call it d) and its type (DictType) have a __repr__ method: repr(d) returns "d", and repr(DictType) returns "<type 'dictionary'>". Given the analogy with classes, where str(x) invokes x.__str__() and x.__str__() can also be called directly, it is not unreasonable to expect that this works in general, so that repr(d) can be spelled as d.__repr__() and repr(DictType) as DictType.__repr__() And, given another analogy with classes, where x.foo() is equivalent to x.__class__.foo(x), the two forms above should also be equivalent to d.__class__.__repr__(d) and DictType.__class__.__repr__(DictType) But since d.__class__ is DictType, we now have two conflicting ways to derive a meaning for DictType.__repr__: the first one going repr(DictType) => DictType.__repr__() and the second one going repr(d) => d.__class__.__repr__(d) => DictType.__repr__(d) The rule quoted above chooses the second meaning, from the very pragmatic point that once I allow subclassing from DictType, such a subclass might very well want to override __repr__ to wrap the base class __repr__, and the conventional way to reference that (barring the implementation of 'super') is DictType.__repr__. Direct invocation of an object's own __repr__ method as x.__repr__() is much les common. The implementation of repr(x) can do the right thing, which is to look for x.__class__.__dict__['__repr__']. > The problem with the misleading error message would only show > up in case DictType does not define a __repr__ method. Then the > inherited one from TypeType would come into play and cause > the problem you mention above. No, the issue is not inheritance: I haven't implemented inheritance yet. DictType is an instance of TypeType but doesn't inherit from it. > Thinking in terms of meta-classes, I believe we should implement > this mechanism in the meta-class (TypeType in this case). Its > __getattr__() will have to decide whether or not to expose its > own methods and attributes or not. That's exactly how I solved it: type_getattro() implements the rule quoted at the top. > The only catch here is that currently instances and classes have > control of whether and how to bind found functions as methods or not. > We should probably change that to pass complete control over to the > meta-class object and remove the special control flows currently found > in instance_getattr2() and class_lookup(). Um, yeah, that's where I think this will end up causing more trouble. Right now, if x is an instance, some attributes like x.__class__ and x.__dict__ special-cased in instance_getattr(). The mechanism I propose removes the need for (most of) such special cases, and instead allows the class to provide "descriptors" for instance attributes. So, for example, if instances of a class C have an attribute named foo, C.__dict__['foo'] contains the descriptor for that attribute, and that is how the implementation decides how to interpret x.foo (assuming x is an instance of C). We may be able to access this same descriptor as C.foo, but that's really only important for backwards compatibility with the way classes work today. > In general, I think that meta-classes should not expose their > attributes to the class objects they create, since this causes > way to many problems. I agree. > Perhaps I'm oversimplifying things here, but I have a feeling that > we can go a long way by actually trying to see meta-classes as > first class members in the interpreter design and moving all the > binding and lookup mechanisms over to this object type. The special > casing should then take place in the meta-class rather than its > creations. Yes, that's where I'm heading! --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