On Feb 7, 2014 1:39 PM, "Clavier" <[email protected]> wrote: > > > > On Friday, February 7, 2014 8:25:10 AM UTC+9, C Anthony Risinger wrote: >> >> On Wed, Feb 5, 2014 at 3:50 PM, Clavier <[email protected]> wrote: >>> >>> Hi. >>> >>> I am trying to see whether I can implement __getattr__() which is called when a method does not exist. I have to use a very long unreadable call in the current version of Pyjs: >>> >>> server=WebRpc('http://server.com/') >>> server.request(arg1, arg2) # Python call >>> server.__getattr__('request').__call__(arg1, arg2) # Pyjs call because __getattr__() is not automatically called >>> >>> I made a class (WebRpc) that a client can access server-side objects, and this makes client-server programming very simple. In this case, supporting __getattr__() is important because it makes a server-client call exactly like a local call. The current Pyjs doesn't support it, so I have to call it explicitly making the code unreadable. >>> >>> I found a previous discussion about it ( https://groups.google.com/forum/#!topic/pyjamas-dev/_aJ2nmFjjas), but I don't understand why it has a performance issue. I think that a programmer can avoid it by directly calling the method (i.e. "obj.__getattr__('request').call()" instead of "obj.request()") if performance is an issue. >>> >>> Please give me your advice about it (how to implement, caveats, or performance issues, etc). >> >> >> are you building with --enable-accessor-proto? that discussion is from 2009. >> >> this code: >> >> ========================= >> class Hi(object): >> >> def __getattr__(self, key): >> print(key) >> >> hi = Hi() >> print(hi.there) >> ========================= >> >> ...will print 'there' and 'null' to the console. >> >> -- >> >> C Anthony > > > Your example(member referencing: hi.there) worked with and without --enable-accessor-proto. But my application including method calls (i.e. hi.there()) building with --enable-accessor-proto still didn't work. I think that the current Pyjs throws an error on a method call(hi.there()), but not on member reference (hi.there) regardless of the option. > > Following is the simplified code I tested: > >> ####################### >> # test __getattr__() >> class Hi2(): >> def __init__(self, name): >> self.name=name >> def __call__(self): >> print 'Hi2.%s() was called'% (self.name) >> class Hi(object): >> def __getattr__(self, key): >> print 'in Hi.__getattr__(%s)' % key >> return Hi2(key) >> hi = Hi() >> hi.there #member reference >> hi.there() #method call > > > Python result : >> >> in Hi.__getattr__(there) >> in Hi.__getattr__(there) >> Hi2.there() was called > > > Pyjs result (IE and FireFox): >> >> in Hi.__getattr__(there) >> >> Unknown exception: [object Error] >> Traceback: >> test_getattr.py, line 17: >> hi.there() > > > As you can see, member reference(hi.there) worked, but method call (hi.there()) threw an exception.
This is expected behavior though? As your example demonstrates, pyjs does not currently support __call__. This doesn't mean it isn't handling the __getattr__ call; ultimately it's failing because you're trying to call an instance (tho I can't comment offhand why you only see one print) . Try putting a print in the __init__ def of the proxied class, and I believe you will see it created twice. Also, replace __call__() with call(), then invoke with hi.there.call()... I'm pretty sure that will work as well. If you take a look at the generated JavaScript you will see most attribute access is transformed into getattr() calls; also take a look at translater_proto.py if you want to explore further, because that is where getattr (and most other AST magic) is actually handled. would be nice to have __call__ though... -- C Anthony [mobile] -- --- You received this message because you are subscribed to the Google Groups "Pyjs.org Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
