473,326 Members | 2,128 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

pondering about the essence of types in python

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.

-tomer

Mar 25 '06 #1
6 1449
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

Mar 25 '06 #2
i was taking about python...

Mar 26 '06 #3
gangesmaster wrote:
but __mro__ is a readonly attribute, and deriving from instances is
impossible (conn.modules.wx.Frame is a PROXY to the class)...


Maybe I'm misunderstanding, but why is an instance a proxy to a class?
Why don't you make a class a proxy to the class?

STeVe
Mar 26 '06 #4
i dont think it's possible, to create proxy classes, but even if i did,
calling remote methods with a `self` that is not an instance of the
remote class would blow up.
-tomer

Mar 26 '06 #5
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 <al***************@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
Mar 26 '06 #6
gangesmaster wrote:
i dont think it's possible, to create proxy classes, but even if i did,
calling remote methods with a `self` that is not an instance of the
remote class would blow up.


I don't understand you here. Why can't you just do something like:
class RemoteClass(object): .... def __init__(self, name):
.... self.name = name
.... def __repr__(self):
.... return '%s(name=%s)' % (type(self).__name__, self.name)
.... rc = RemoteClass('foo')
rc RemoteClass(name=foo) class ProxyClass(object): .... def __init__(self, name):
.... self.remote = RemoteClass(name)
.... def __repr__(self):
.... return repr(self.remote)
.... pc = ProxyClass('foo')
pc

RemoteClass(name=foo)

Note that when I call methods on the remote class, I don't pass them an
instance of the proxy class -- I pass them an instance of the
appropriate, RemoteClass type. Of course my code is simplified because
I'm not actually doing something remote, but assuming things get, say,
pickled and unpickled appropriately, I'm not sure I understand why the
above won't work.

Could you give some more details?

STeVe
Mar 26 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
by: Gordon Airport | last post by:
Has anyone suggested introducing a mutable string type (yes, of course) and distinguishing them from standard strings by the quote type - single or double? As far as I know ' and " are currently...
7
by: svilen | last post by:
hello again. i'm now into using python instead of another language(s) for describing structures of data, including names, structure, type-checks, conversions, value-validations, metadata etc....
8
by: Jacek Generowicz | last post by:
I am writing an extension type, and wish to add some magic methods which are not catered for by the tp_<whatever> slots (eg tp_init -> __init__) in PyTypeObject. My methods seem to work correctly...
24
by: Matt Feinstein | last post by:
Hi all-- I'm new to Python, and was somewhat taken aback to discover that the core language lacks some basic numerical types (e.g., single-precision float, short integers). I realize that there...
0
by: Pete Shinners | last post by:
I've been spending the last few night upgrading some 'classic' type objects to the more modern 'newstyle' types. Unless I am not finding some important page, this entire process is almost entirely...
2
by: j_mckitrick | last post by:
I recently took a one week course on .NET, and they emphasized over and over again that the key is types. Everything is strongly typed and enforced. Python is the exact opposite. Yet both...
0
by: Brett C. | last post by:
My thesis, "Localized Type Inference of Atomic Types in Python", was successfully defended today for my MS in Computer Science at the California Polytechnic State University, San Luis Obispo. With...
15
by: pranab_bajpai | last post by:
So I want to define a method that takes a "boolean" in a module, eg. def getDBName(l2): .... Now, in Python variables are bound to types when used, right? Eg. x = 10 # makes it an INT...
7
by: Maximus Decimus | last post by:
HI all, I am using python v2.5 and I am an amateur working on python. I am extending python for my research work and would like some help and guidance w.r.t this matter from you experienced...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.