pondering about the essence of types in python
Alan Franzoni
alan.franzoni.xyz at gmail.com
Sun Mar 26 09:30:04 EST 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