On Wed, Sep 19, 2012 at 12:40 PM, Michael Moore
<[email protected]> wrote:
> I am getting an error.
>
> newsink AttributeError: '<AlphaListBoxsetup object>' has no attribute
> 'onalphaItemSelected'
>
> class AlphaListBoxsetup(SimplePanel):
>     def __init__(self):
>         SimplePanel.__init__(self)
>         self.list1=ListBox()
>         self.list1.setVisibleItemCount(8)
>         A.alpha.sort()
>         for item in A.alpha:
>             self.list1.addItem(item)
>         self.add(self.list1)
>         self.list1.addChangeListener(getattr(self, 'onalphaItemSelected'))
>
>     def generic(self):
>         item = self.list1.getItemText(self.list1.getSelectedIndex())
>         Window.alert("You selected %s from the stack Alphabetic" %(item))
>     generic.__name__ = 'onalphaItemSelected'
>     locals()['onalphaItemSelected'] = generic
>
> is the relevant code.  Of course, with the def generic() line changed to def
> onalphaItemSelected(), it works just fine.
>
> I have a situation where I do not know until runtime how many listboxes with
> selections I need to produce.  This may be an area where Python will and
> Pyjs won't, but in Python that code should allow the generation of functions
> with names set from strings.  Immediate mode example follows:
>
>>>>> def generic(x):
> ....   return x**2
> ....
>>>>> globals()['squareit']=generic
>>>>> squareit(25)
> 625
>>>>> def generic(x):
> ....   return x**3
> ....
>>>>> globals()['cubeit']=generic
>>>>> squareit(25)
> 625
>>>>> cubeit(25)
> 15625
>>>>>
>
>
> This allows the definition of functions whose names are generated by code
> without resorting to metaprogramming with exec, but it seems not to work in
> Pyjs.
>
> Any suggestions for accomplishing this?  I have a group of scripts to be
> picked to be part of a workflow, and I have one list where they are in
> alphabetical order, then another list of those used most frequently, then
> another list of those concerned with just alignment, and so on.  Many tags
> are possible and more functional tags may be added to the script nodes at
> any time, so when the list of scripts is pulled from the database, the tags
> are basically a list for each script that defines every folder in which the
> script name should appear.  I have no difficulty generating that on the
> controller, but when I shoot that information over as a JSON object, I have
> to manufacture a stack panel full of lists and allow one choice from one
> selected list.

i can't get too in depth with your code here, but since a few of your
other posts have similar issue i thought i would try and alleviate
some of your pain.

first off, avoid unnecessary logic during class creation.  try using
setattr() after the fact, or using the 3-arg type() class constructor.
 this is a scoping problem/bug in pyjs ... do the logic outside class
creation.

tbh, i'm not sure the status of globals() and locals() off-hand, but
neither are required for dynamic creation of object members ... ever.
using them for such makes the code less understandable, and may rely
on implementation details, eg. for locals():

Note The contents of this dictionary should not be modified; changes
may not affect the values of local and free variables used by the
interpreter.

... straight from python 2.7 docs.  globals is simply the __dict__ of
a module, so:

import moduleX
setattr(moduleX, some_identifier_that_is_dynamic, func)

... is exactly the same as performing:

globals()[some_identifier_that_is_dynamic] = func

... from within `moduleX`.  while i'm not sure off-hand pyjs will
tolerate it, i have in the past imported the current module, and
setattr() on itself ... you simply can't use symbols that have not
been created yet.  for example, to maintain backward compatibility, i
did this in pyjd/__init__.py:

#TODO: very ugly to self-import and setattr(self) ... remove ASAP!
import pyjd
[...]
for key, value in _manager._conf.iteritems():
    setattr(pyjd, key, value)

... in short, there is nothing here that setattr()/getattr() cannot
handle; i think if you reorganize a bit, and shoot for less exotic
patterns, you will have no trouble squeezing all the dynamism you can
handle from pyjs ;-)

-- 

C Anthony

-- 



Reply via email to