I have an app that uses Python scripting. When a user creates a new object:
objName = newObject()
I'd like the newObject be able to use objName as its internal name. So, if a user says:
cube1 = Cube()
A "cube1" object should apear in the scene list. I believe this means I need to determine that a namespace assignment is going on from inside the object's init code or by using properties.
I've searched the web but can't find a simple answer. Is there some way to use the inspect module get source code functoins? How would I get the code for "the current interpreter line" causing the init code to execute?
> I have an app that uses Python scripting. When a user creates a new object:
> objName = newObject()
> I'd like the newObject be able to use objName as its internal name. > So, if a user says:
> cube1 = Cube()
> A "cube1" object should apear in the scene list. I believe this means I need > to determine that a namespace assignment is going on from inside the > object's init code > or by using properties.
> I've searched the web but can't find a simple answer. Is there some > way to use the inspect > module get source code functoins? How would I get the code for "the > current interpreter line" > causing the init code to execute?
> Thanks very much in advance, > Jamie Riotto
Save yourself a lot of trouble and just assign a name "manually":
class foo: def __init__(self, name): self.name = name
> I have an app that uses Python scripting. When a user creates a new object:
> objName = newObject()
> I'd like the newObject be able to use objName as its internal name. > So, if a user says:
> cube1 = Cube()
> A "cube1" object should apear in the scene list. I believe this means I need > to determine that a namespace assignment is going on from inside the > object's init code > or by using properties.
As the others already explained to you there is no way to archive your goal with an assignment to a local or global variable. But you can follow a different approach:
class Scene(object): def __setattr__(self, name, value): super(Scene, self).__setattr__(name value) if isinstance(value, SceneObject): value.name = name value.scene = self
> I have an app that uses Python scripting. When a user creates a new object:
> objName = newObject()
newObject should technically speaking be newClass() but nevermind :-)
> I'd like the newObject be able to use objName as its internal name. > So, if a user says:
> cube1 = Cube()
> A "cube1" object should apear in the scene list. I believe this means I need > to determine that a namespace assignment is going on from inside the > object's init code > or by using properties.
A class's init code is like a constructor (guessing you know about ctors here). Basically, initialising all the variables that particular class uses. In this instance calling Cube( ) would cause it to call up the __init__(self) function in Cube class and do whatever it does there such as defining a variable, calling other initialisation functions etc...
> I've searched the web but can't find a simple answer. Is there some > way to use the inspect > module get source code functoins? How would I get the code for "the
To get the source code for a function, you can manually inspect it. To get the functions that a class exports, use can use dir(object_of_a_class) in Python shell (this may not be what you want but I write it anyway because I feel like writing today). You can also run help(module_name_here) to see the docs+functions.
> current interpreter line" > causing the init code to execute?
I am starting to suspect that you are very much asking for a debugger ;-) Look up pdb;a Python debugger. -- Regards, Ishwor Gurung
> Jamie Riotto schrieb: >> I have an app that uses Python scripting. When a user creates a new >> object:
>> objName = newObject()
>> I'd like the newObject be able to use objName as its internal name.
> As the others already explained to you there is no way to archive your > goal with an assignment to a local or global variable. But you can > follow a different approach:
> class Scene(object): > def __setattr__(self, name, value): > super(Scene, self).__setattr__(name value) > if isinstance(value, SceneObject): > value.name = name > value.scene = self
> class SceneObject(object): > pass
> class Cube(SceneObject): > pass
> scene = Scene() > scene.cube1 = Cube()
As the OP said it's being used for scripting some application, presumably the application can control the environment on which the script is run. One may use the Scene class above as the globlal scope when executing the script:
scene = Scene() code = "cube1 = Cube(); print cube1.name" exec code in Scene
(well, not exactly, Scene should inherit from dict and override __setitem__ instead, but you get the idea)
<gagsl-...@yahoo.com.ar> wrote: > En Fri, 18 Sep 2009 14:38:08 -0300, Christian Heimes <li...@cheimes.de> > escribió:
>> Jamie Riotto schrieb:
>>> I have an app that uses Python scripting. When a user creates a new >>> object:
>>> objName = newObject()
>>> I'd like the newObject be able to use objName as its internal name.
>> As the others already explained to you there is no way to archive your >> goal with an assignment to a local or global variable. But you can >> follow a different approach:
>> class Scene(object): >> def __setattr__(self, name, value): >> super(Scene, self).__setattr__(name value) >> if isinstance(value, SceneObject): >> value.name = name >> value.scene = self
>> class SceneObject(object): >> pass
>> class Cube(SceneObject): >> pass
>> scene = Scene() >> scene.cube1 = Cube()
> As the OP said it's being used for scripting some application, presumably > the application can control the environment on which the script is run. One > may use the Scene class above as the globlal scope when executing the > script:
> scene = Scene() > code = "cube1 = Cube(); print cube1.name" > exec code in Scene
> (well, not exactly, Scene should inherit from dict and override __setitem__ > instead, but you get the idea)
Thanks for the detailed clarifications and suggestions. I understand the problem a lot better now. However, I'll have to keep looking for a more elegant solution. Telling a user that typing: cube1 = Cube(name = cube1) is a good thing because its pythonic is somehow unsatisfying.
Also, in the last suggestion about execution the script in the Scene Handler global scope, well thats exactly what I do, and yes, cube1=Cube, print cube1.name works great. The issue is say perhaps that cube then collides with something called sphere1. How does cube1 know that it hit "sphere1" and not just a sphere object. Since I can execute the scripts one line at a time, I suppose I could search dictionaries for new names pointing to the same object after every execution, but Yuck.
Perhaps the best approach is a preprossesor that looks for lines of the form "name = class()" and adds in the class(name = name) behind the scenes. Thanks again - jamie
On Fri, Sep 18, 2009 at 6:57 PM, Jamie Riotto <jamie.rio...@gmail.com> wrote: > However, I'll have to keep looking for a more elegant solution. > Telling a user that typing: > cube1 = Cube(name = cube1) is a good thing because its pythonic is > somehow unsatisfying.
That isn't pythonic. The usual pythonic way to map names to objects is to use one of python's most used datatypes: the dictionary. So they might do something like this:
scene["Cube1"] = Cube(xpos, ypos, zpos)
You could either have your Scene class inherit from dict, or write custom __getattr__ and __setattr__ methods for it. Alternatively, you could add functions to your Scene class that manipulate a dictionary that isn't directly exposed, and your users could do something like this:
scene.add_item("Cube1", Cube(xpos, ypos, zpos))
Where the add_item method of the Scene would keep an internal dictionary of all of the objects in the scene.