Alex
Alex

Reputation: 1464

How can I instantiate a variable?

I have the following:

define.py:

 class Place:
     def __init__(self,name,inhabitants):
         self.name=name
         self.inhabitants=inhabitants
         myFunction.toStoreThings.on.db(name,inhabitants,'places')
     def someUsefulFunction(self):
         pass

If I run import objects, moon=objects.Place('Moon',[]), close the interpreter and open it again. I obviously loose the moon instance, but I have (u'Moon',u'[]') stored in the database. I already made __init__.py retrieve that information from the database and unstring it, but I'd also like it to instantiate 'Moon' as Moon=Place('Moon',[]) so I can use Moon.someUsefulFunction() or objects.Moon.someUsefulFunction() even after I close the interpreter. How can I achieve this?


I was able to do it like this:

__init__.py:

# myFunction() creates a dictionary `objdic` of the stuff in the database
# >>>objects.objdic
# {'places' : [['Moon',[]]]}
instancesdic={}
instancesdic['places']={}
instancesdic['places'][objdic['places'][0][0]]=Place(*objdic['places'][0])

Which gives

>>> objects.instancesdic
{'places': {'Moon': <objects.Place instance at 0x1b29248>}}

This way I can use

objects.instancesdic['places']['Moon'].someUsefulFunction()

Which is ok, but I really wanted objects.Moon.someUsefulFunction(). Any attempt to call that whole thing Moon results either in:

TypeError: 'str' object does not support item assignment

Or in just the key in the dictionary being changed to an instance, instead of the Moon instance being created.

Upvotes: 1

Views: 80

Answers (1)

BrenBarn
BrenBarn

Reputation: 251398

You could use the setattr function to set module attributes on the objects module, or you could update globals within that module. So within your __init__.py you could do:

objDict = {obj[0]: Place(*obj) for obj in objdict['places']}
globals().update(objDict)

This will then let you do object.Moon, etc.

There is some danger to be aware of, though. If any of your objects have the same name as anything else already created in objects, they will overwrite those things. So if objects has a function called myFunc and then you create an object called myFunc, it could overwrite the function with the object. (Which will overwrite which depends on which order you do things in.)

For this reason, it's probably not a good idea to do this automatically in __init__.py. It can make sense to do this for ease of use in the interactive interpreter, but modifying globals in this way will get ugly if you use it in scripts. It might be a better idea to create a function called initGlobals or something, and then call that function to set up your interactive environment. If you put the code I showed above into such a function, then call it, it will set up the environment. This lets you separate the simple importing of the module from actually creating global objects from the db, because sometimes you might want to do one but not the other.

Upvotes: 1

Related Questions