lkcl a écrit :
On Oct 3, 10:29 am, Bruno Desthuilliers <bruno.
[EMAIL PROTECTED]> wrote:
lkcl a écrit :> On Oct 2, 7:42 pm, Bruno Desthuilliers
<[EMAIL PROTECTED]> wrote:
lkcl a écrit :

And as far as I'm concerned, the point is
exactly here : it's doing "a little bit more" than the original code.

 yeah, i know.  and that "bit more" gets you a proper representation
of the python "class" concept.

Except that in most cases - at least when it comes to browser scripting[1] - this concept is just useless. IOW, that's quite a lot of code for something you just don't need.

[1] but ask yourself how many times you end up having only one single instance of a given class in a python utility script...

 i was merely pointing out that if you want to _really_ translate the
original code into python - _really_ strictly - it's not actually
possible.

"really strictly", nope. But mainly because there's nothing in Python that behave like the 'this' javascript object (and it doesn't matter in the OP snippet). But you can have something quite close, using the class as an object (which it is anyway).

 because python doesn't have the concept of non-prototyping
(but... see below: i believe i may stand corrected on that)

!-)

Indeed. But the point is that Python - while close to a prototype-based
language in many aspects - is still class-based. The closer Python
translation of the OP's javascript snippet is probably the one I gave
using a 'class singleton' - that is, using the class itself as an
object.

 oh is _that_ how you do it.  thanks.  i always wondered how you did
class singletons in python.

Note that this not really idiomatic Python - partly for cultural reasons, and mostly because use case and constraint differs (class singleton would surely become idiomatic if Python was used as browser-scripting language the way js is, because you then have to avoid any useless code to keep the site responsive).

Anyway, that's still IMHO the pythonic way to translate a litteral javascript object - I fail to see anything closer in Python (if there's some guru around ?)

python-source-to-javascript-source tool like pyjamas won't give you back
the original javascript snippet (which is by no mean a criticism of
pyjamas - it would just be way too complicated to automatize such a
translation).

 well... you _say_ that... but... actually, if that's the real way to
represent class singletons, and it's an accurate representation of the
OP's javascript, and a good example, then _yes_, pyjs should
definitely have that added as a feature - to understand that a class
singleton _can_ get mapped to the much more efficient javascript
example you gave.

I'm afraid it's going to be quite complicated. You'd have to make sure the class only has classmethods - including inherited methods (and exception made of methods inherited from object). And FWIW, even such a class may be a base class for 'normal' python classes, so there's just no reliable semantic way to make sure the class is really a class singleton that should map to a litteral js object.

See, the problem here is that we have two high level, highly dynamic languages, that are quite close on quite a lot of things but are based on two really different object models. So quite often, the best translation is obvious for a programmer with a decent knowledge of both languages, but almost impossible for a program because there are way too much imply stuff (like, for the python class singleton, the fact that the class is not meant to be instanciated is totally implicit).

not that many people would _want_ to do that,

Err... Do you have much experience in browser scripting ??? That's a *very* common js idiom.

so it goes onto the
"diminishing returns TODO list", but...

Nope. You defined functions outside the object's scope, and you still
have to instanciate dataListener. Also, this above code just won't work
- unless you explicitely pass the dataListener instance to the
functions, ie:

d = dataListener()
d.onDataAvailable(d, ...)

 yeah - i didn't realise what the python class singleton thing was.

In this case, the problem I pointed out was that Python's functions needs to be class instances to yield instancemethods when looked up on an instance or class. If you set a function as an instance attribute, the descriptor protocol is not invoked, and you just have a plain function (note that this is by design).

It seem you didn't read my other translation proprosal, so I repost it here:

class dataListener(object):
    data = ''

 i did - i just didn't understand its significance.

 so - to get this straight: when you do class clsname(object), and you
have the indentation and declaration of variables (e.g. data, above)
at the same level as the functions, it means that there's only one of
them? (i.e. a singleton)?

Nope. Whatever is declared within the class statement becomes a class attribute - that is, an attribute of the class object, shared by all instances. But that doesn't prevent you from instanciating the class and set an instance attribute by that name, in which case it will shadow the class attribute.

so, if i do this:

d = dataListener()
e = dataListener()

d.data = "fred"

print f.data

will return "fred"?


Nope. The lookup rules for "reading" are:
- first check if the class (or it's bases, following mro) has a __getattribute__ method. If yes, call it, and stop here whatever the result. - else check if there's a descriptor by that name in the class (including bases etc) - if not, check if the instance has a non-descriptor attribute by that name in it's dict - else check if the class (and it's bases etc) has a non-descriptor by that name - else lookup if the class (etc...) have a callable __getattr__ attribute and if yes call it with the looked up name
- else (if nothing matched so far) raise an attribute error

When it comes to 'writing', it's much more simple:
- first check if the class (and it's bases...) have a __setattr__ method. If yes, call it with the name and value and stop here whatever happens. - else check if the class (and it's bases etc...) have a descriptor by that name _with binding behaviour_ (IOW : with a __set__ method). If yes, call the descriptor's __set__ method with instance, name and value.
- else just set the instance's __dict__ with the name and value.

NB : I didn't mention slots, but they are rarely used. I leave it up to you to read the relevant doc for more detailed informations.

To make a long story short, in your above snippet, the d.data = "fred" statement ends up being a shortcut for d.__dict__['data'] = "fred". To have the class singleton working as an object, you must not instanciate it - just use the class object directly, ie:

class dataListener(object):
    data = ""

dataListener.data = "fred"
print dataListener.data

If you really want to prevent dataListener from being instanciated, you'd have to provide a __new__ method preventing instanciation, ie:

class dataListener(object):
    def __new__(cls):
        raise TypeError("class %s is a class singleton" % cls)

HTH
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to