pondering about the essence of types in python

Alan Franzoni alan.franzoni.xyz at gmail.com
Sun Mar 26 16:30:04 CEST 2006


gangesmaster on comp.lang.python said: 

> TypeError: unbound method __init__() must be called with z instance as
> first argument (got x instance instead)
> ==========
> 
> and the question is -- WHY?

I think the answer would be: because it's an instance method. Its
'contract' it's to be bound to an object of a certain class. Would you like
a different behaviour, you could decorate whatever method you need. I.e.,
turn your example into:

class z(object):
    @staticmethod
    def __init__(self):
            self.blah=5

class x(object):
    def __init__(self):
            z.__init__(self)


y = x()


And this will work as you wish. You could have used classmethod as well
with a properly tuned init, of course.
 
> 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?

I really think this happens because Python was designed to be
casualerror-safe. This approach would probably lead to many programming
errors. 

By the way, Python was designed to *discourage* such behaviours, not to
prevent them. By the way, I didn't grasp what you would really like to do.
You're saying you want to derive from instances, but then I see in your
sample code you're creating a *class* derived from an object (I would
expect you would like to derive an instance from an instance, and to
'twist' such new instance methods to your needs, which I think can be done
as well). What's the difference between that and the use of __class__ ?

class z(object):
    @staticmethod
    def __init__(self):
            self.blah=5

    @staticmethod
    def met_stat(self):
        pass

    @classmethod
    def met_cls(self):
        pass

    def met_inst(self):
        pass
    


class x(object):
    def __init__(self):
            z.__init__(self)


y = x()


class q(y.__class__):
    pass


r = q()


This work OK to me. Unless you want to do something like making y instance
attributes become q class attributes, or you would like to set y instance
attributes on all q instances, which could require a bit more of code but
surely can be done. This would mix up a bit the class vs instance
behaviour, though, e.g. changing a derived class instance attribute which
is inherited from a parent instance would lead to a global attribute
change, or would 'spawn' a new instance attribute for that particular
instance?

> def derive_from(obj):
>     class cls(object):
>         def __getattr(self, name):
>             return getattr(obj, name)
>     return cls

This seems to work for deriving read-only data from instances (no way to
write back data).
 
> 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.

You don't HAVE TO check types if you don't want. Just use @staticmethod
everywhere in your classes. I mean, a METHOD is supposed to be
class-related, and it's often useful to have it as such, (unexpected errors
and behaviours might rise everywhere if not so), but you're never forced to
use that.


-- 
Alan Franzoni <alan.franzoni.xyz at gmail.com>
-
Togli .xyz dalla mia email per contattarmi.
Rremove .xyz from my address in order to contact me.
-
GPG Key Fingerprint:
5C77 9DC3 BD5B 3A28 E7BC 921A 0255 42AA FE06 8F3E



More information about the Python-list mailing list