Great exercise for python expert !

Peter Otten __peter__ at web.de
Fri Nov 28 11:12:35 EST 2008


manatlan wrote:

> To explain better, here is another code


> class JQueryCaller(object):
>     def __init__(self,callback):
>         self.__callback=callback
>         self._s=[]
> 
>     def __getattr__(self,name):
>         def _caller(*args):
>             sargs=["'%s'"%i for i in args]
>             self._s.append("%s(%s)"%(name,",".join(sargs)))
>             return self
>         return _caller
> 
>     def __call__(self):
>         return self.__callback(".".join(self._s))
> 
> 
> class MyObject(list):
>     def __init__(self):
>         list.__init__([])
> 
>     js=property(lambda self:JQueryCaller(self.__add))
> 
>     def __add(self,j):
>         self.append(j)
> 
> 
> if __name__ == "__main__":
>     o=MyObject()
> 
>     o.js.kiki(12).kuku()()
>     o.js.kiki(12).kuku().roro("gfde")()
> 
>     assert o==["kiki('12').kuku()", "kiki('12').kuku().roro('gfde')"]


> here, it uses the __call__ of JQueryCaller by adding the "()" trick at
> the end ...
> 
> I'd really like to have the same result, without the "()" trick, like
> this:
> 
>     o=MyObject()
> 
>     o.js.kiki(12).kuku()
>     o.js.kiki(12).kuku().roro("gfde")
> 
>     assert o==["kiki('12').kuku()", "kiki('12').kuku().roro('gfde')"]


You could preallocate slots in MyObject:

from functools import partial

class JQueryCaller(object):
    def __init__(self,callback):
        self.__callback=callback
        self._s=[]

    def __getattr__(self,name):
        def _caller(*args):
            sargs=["'%s'"%i for i in args]
            self._s.append("%s(%s)"%(name,",".join(sargs)))
            self.__callback(".".join(self._s))
            return self
        return _caller

class MyObject(list):
    def __init__(self):
        list.__init__([])
        
    @property
    def js(self):
        n = len(self)
        self.append(None)
        return JQueryCaller(partial(self._add, n))

    def _add(self, i, j):
        self[i] = j

if __name__ == "__main__":
    o=MyObject()

    o.js.kiki(12).kuku()
    o.js.kiki(12).kuku().roro("gfde")

    assert o==["kiki('12').kuku()", "kiki('12').kuku().roro('gfde')"]

This will course fail if you try things like

a = o.js.kiki
a(1)
a(2)

Peter




More information about the Python-list mailing list