pondering about the essence of types in python
Steve Holden
steve at holdenweb.com
Sat Mar 25 17:09:30 EST 2006
gangesmaster wrote:
> let's start with a question:
>
> ==========
>
>>>>class z(object):
>
> ... def __init__(self):
> ... self.blah=5
> ...
>
>>>>class x(object):
>
> ... def __init__(self):
> ... z.__init__(self)
> ...
>
>>>>y=x()
>
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File "<stdin>", line 3, in __init__
> TypeError: unbound method __init__() must be called with z instance as
> first argument (got x instance instead)
> ==========
>
> and the question is -- WHY?
>
> what is a type? generally speaking, if everything were an object, the
> type only defines the MRO (method resolution order) for that object.
> x.y first looks at the instance, then the class, then the parent
> classes, etc. (this was changed a little in python2.3 to something more
> complicated, but it's basically the same).
>
> you can see the mro like this:
> ==========
>
>>>>class x(object): pass
>>>>class y(x): pass
>>>>class z(y): pass
>>>>a=z()
>>>>print a.__class__.mro()
>
> [<class '__main__.z'>, <class '__main__.y'>, <class '__main__.x'>,
> <type 'object'>]
> ==========
>
> after all, if we stay out of builtin types, all python objects are
> dicts, which support chian-lookup according to the mro. and a method is
> just a function that takes the instance as a first argument. so why is
> all this type hassle necessary?
>
> if we've taken it that far already, then let's really go over the edge.
> I WANT TO DERIVE FROM INSTANCES. not only types.
>
> why? i'm the developer of rpyc (http://rpyc.sf.net), and i got a
> request from someone to add support for deriving from remote types. the
> concrete example he gave was quite silly, but after i thought about it
> a little, i said why not try?
>
> a little intro about rpyc: it gives you proxies (instances) to remote
> objects, which can be instances, functions, or classes. and that user
> wanted to do something like this:
>
> class my_frame(conn.modules.wx.Frame):
> ...
>
> so the client was actually creates the graphics on the server. not very
> usable, but why not? all it means is, when he does "my_frame.xyz",
> python should add the remote type to the mro chain. not too bizar.
>
> but __mro__ is a readonly attribute, and deriving from instances is
> impossible (conn.modules.wx.Frame is a PROXY to the class)...
>
> and again -- WHY? these all look like INTENTIONAL limitations. someone
> went around and added type checks (which are NOT pythonic) into the
> cPython implementation. argh. why do that?
>
> so i thought -- let's be nasty. i created a function that creates a
> class that wraps an instance. very ugly. small children and peope with
> heart problems should close their eyes.
>
> ============
> def derive_from(obj):
> class cls(object):
> def __getattr(self, name):
> return getattr(obj, name)
> return cls
>
> class my_frame(derive_from(conn.modules.wx.Frame)):
> ....
> ============
>
> the actual implementation is quite more complex, but that shows the
> concept.
> so now i'm experimenting with that little shit. but then i came to the
> problem that methods check the type of the first argument... ARGH. dont
> check types. DONT. the whole point of duck-typing is you DONT CHECK THE
> TYPES. you just work with objects, and instead of TypeError you'd get
> AttribiuteError, which is much better. AAARRRRRRGGGHH.
>
> python is EVIL at the low level. the high-level is just fine, but when
> you try to go under the hood... you better go with an exorcist.
>
Take a look at languages like Self. Self was actually the first
prototype-based OO language. You could consider Javascript to be a
prototype-based language as well.
regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd www.holdenweb.com
Love me, love my blog holdenweb.blogspot.com
More information about the Python-list
mailing list