Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > using names before they're defined

Reply
Thread Tools

using names before they're defined

 
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      07-20-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
(snip)
> brings me onto another question that has been bugging me, which is, if
> I want to create components (as object instances) at run time (rather
> than through a python code imported in), how do I do this? i.e. if I
> hardcoded something like
> turbine1 = turbine(...)
> then python knows that turbine1 is a turbine. but if I had say some
> kind of user interface and I want to create turbine1 (or suchlike) on
> the fly, how do I actually do that? how do I create objects after run
> time?


Q&D possible solution, no error handling, etc
....just so you get an idea

# schema generated by a GUI
# or directly written in a .py config file
# or whatever

schema = {'turbine1': {'class': 'Turbine',
'upstream' : ('frobnicator2',),
'downstream' : () # nothing,
},
'frobnicator2' : {'class' : 'Frobnicator',
'upstream' : (),
'downstream' : ('frobnicator2',),
},
}

# code:

def get_class_by_name(name):
return globals()[name]

def chain_from_schema(schema):
objects = {}
for name, desc in schema:
klass = get_class_by_name(desc['class'])
objects[name] = klass()
for name, desc in schema:
target = objects[name]
ups = [objects[upname] for upname in desc['upstream']]
downs = [objects[downname] for downname in desc['downstream']]
target.links(upstream=ups, downstream=downs)
return objects


--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '(E-Mail Removed)'.split('@')])"
 
Reply With Quote
 
 
 
 
davehowey@f2s.com
Guest
Posts: n/a
 
      07-20-2006
Hiya

Could you just talk me through this... is it:

> schema = {'turbine1': {'class': 'Turbine',
> 'upstream' : ('frobnicator2',),
> 'downstream' : () # nothing,
> },
> 'frobnicator2' : {'class' : 'Frobnicator',
> 'upstream' : (),
> 'downstream' : ('frobnicator2',),
> },
> }
>


ok, so schema is a dictionary of different components, defining what
class they are and what they're connected to.

> def get_class_by_name(name):
> return globals()[name]


what does this function do exactly?

> def chain_from_schema(schema):
> objects = {} # so objects is our list of objects ?
> for name, desc in schema: # can you step through a dictionary like this?
> klass = get_class_by_name(desc['class']) # does this create an object called klass?
> objects[name] = klass()



sorry for being dim..
Dave

 
Reply With Quote
 
 
 
 
Larry Bates
Guest
Posts: n/a
 
      07-20-2006
I don't know if you saw my earlier post but something like
this has worked for me.

What about something like:

supply = supply()
compressor = compressor(supply)
combuster1= combuster(compressor)
combuster2= combuster(compressor)
compressor.append(combuster1)
compressor.append(combuster2)

or perhaps

compressor.extend([combuster1, combuster2])


turbine = turbine(combuster)
combuster.append(turbine)


If you implement .append and .extend methods
on your classes they will allow you to append single
downstream objects or extend with a list of them.
Just keep a list self.downstream and append/extend
it. IMHO it makes what is going on intuitively obvious.

-Larry Bates

(E-Mail Removed) wrote:
> Bruno,
>
> Thanks. An issue is that I need to be able to link multiple objects to
> a single object etc.
> Say for example using the previous wording, I might have compressor -
> multiple combustors - turbine
>
> this complicates things slightly.
>
> my current thought is to do a two stage initialisation
>
> 1. create the objects
> compressor = compressor()
> combuster1 = combuster()
> combuster2 = combuster()
>
> etc
>
> 2. link them
> compressor.link(downstream = [combuster1, combuster2])
> combuster1.link(upstream = compressor)
> etc.
>
> hmmmm I need to give it some more though, particularly how I solve all
> the linked objects (which is the point)
>
> Dave
>

 
Reply With Quote
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      07-20-2006
(E-Mail Removed) a écrit :
> Hiya
>
> Could you just talk me through this... is it:
>
>
>>schema = {'turbine1': {'class': 'Turbine',
>> 'upstream' : ('frobnicator2',),
>> 'downstream' : () # nothing,
>> },
>> 'frobnicator2' : {'class' : 'Frobnicator',
>> 'upstream' : (),
>> 'downstream' : ('frobnicator2',),
>> },
>> }
>>

>
>
> ok, so schema is a dictionary of different components, defining what
> class they are and what they're connected to.


Yeps.

Note that it could as well be a list of tuple or anything like this, ie:
schema = [
('turbine1', 'Turbine', ('frobnicator2',), ()),
('frobnicator2', 'Frobnicator', (), ('frobnicator2',),
]

I choose a dict for readability.

Also, I gave the example using Python code as 'config' format, but any
structured enough text format could do, ie JSON, XML, or even ini-like:

# schema.ini
objects = turbine1, frobnicator2

[turbine1]
class=Turbine
upstream=frobnicator2
downstream=

[frobnicator2]
class=Frobnicator
upstream=
downstream=turbine


Now you just read the file with the standard config parser and build
your chain from it... (implementation left as an exercice...)


>>def get_class_by_name(name):
>> return globals()[name]

>
>
> what does this function do exactly?


Q&D way to retrieve the class object (Python's classes are themselves
objects) known by it's name (as a string).

globals() returns the module's namespace as a dict object with
'name'bject pairs. This code assume that the name is available in the
current module's namespace, but could be improved to handle needed
imports etc.

>>def chain_from_schema(schema):
>> objects = {} # so objects is our list of objects ?
>> for name, desc in schema:

# can you step through a dictionary like this?

Nope, sorry, it's a mistake I do over and over. It's of course:;
for name, desc in schema.items():

(note that you can iterate over a dict's keys with 'for k in thedict:' )

>> klass = get_class_by_name(desc['class'])

# does this create an object called klass?

Nope, it binds the class object (retrieved by get_class_by_name()) to
the local name 'klass' ('class' is a reserved name).

>> objects[name] = klass()

>
> sorry for being dim..


Where ?

 
Reply With Quote
 
davehowey@f2s.com
Guest
Posts: n/a
 
      07-21-2006
Hi

> Also, I gave the example using Python code as 'config' format, but any
> structured enough text format could do, ie JSON, XML, or even ini-like:
>
> # schema.ini
> objects = turbine1, frobnicator2
>
> [turbine1]
> class=Turbine
> upstream=frobnicator2
> downstream=
>


yes, I like the idea of using .ini type file format or XML, very much.
There are parser available which will automatically building python
objects from this, won't they (like configparser)? I'll have to get
reading over the weekend...

> >>def get_class_by_name(name):
> >> return globals()[name]

> >

>
> Q&D way to retrieve the class object (Python's classes are themselves
> objects) known by it's name (as a string).


ok, so it actually returns the class object itself.
One thing that confuses me is that objects have a name (self.name) but
object instances also have a name (e.g. myspecialturbine = turbine(...)
---- how do I discover the name 'myspecialturbine' ?). And object
instances have a class name too ('turbine'). Aaargh, too many names!
what if just want to know what the name of the instance is (in this
case 'myspecialturbine'?)

Right. I'll have a go at pulling all this together over the weekend
hopefully. Hurrah! Thanks for all the help, to everyone.
Dave

 
Reply With Quote
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      07-21-2006
(E-Mail Removed) wrote:
> Hi
>
>

(snip)
>
>>>>def get_class_by_name(name):
>>>> return globals()[name]
>>>

>>Q&D way to retrieve the class object (Python's classes are themselves
>>objects) known by it's name (as a string).

>
>
> ok, so it actually returns the class object itself.
> One thing that confuses me is that objects have a name (self.name)


They dont - unless you give them one:

>>> class Foo(object): pass

....
>>> Foo.name

Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: type object 'Foo' has no attribute 'name'
>>> f = Foo()
>>> f.name

Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'Foo' object has no attribute 'name'
>>>


classes, functions and modules have a __name__ attribute, but that's
something else...

> but
> object instances also have a name (e.g. myspecialturbine = turbine(...)


Actually, this is the other way round: names refers ('are bound to')
objects. Think of namespaces (the global or local one...) as dicts
holding name:ref-to-object pairs (that's mostly what they are FWIW).
Different names can refer to the same object. The object itself doesn't
know anything about this.

> ---- how do I discover the name 'myspecialturbine' ?).


From within the object refered by this name ? Short answer : you can't.

> And object
> instances have a class name too ('turbine').


Nope, they have a class, which itself as a __name__ attribute, which is
the name that was used when "creating" the class object (ie: usually
when the 'class' statement is eval'd at module load time).

> Aaargh, too many names!
> what if just want to know what the name of the instance is (in this
> case 'myspecialturbine'?)


you just named it so yourself, ie:
myspecialturbine = SpecialTurbine()

Else, no way. You can of course give a name when instanciating the object:

class Named(object):
def __init__(self, name):
self.name = name

n1 = Named('n1')
print n1.name
=> n1

But this doesn't mean there's any correspondance between this name and a
name in the current (or any other) namespace:

toto = n1
n1 = "lalala"
print toto.name
=> n1

locals()[toto.name] is toto
=> False


--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '(E-Mail Removed)'.split('@')])"
 
Reply With Quote
 
Nick Vatamaniuc
Guest
Posts: n/a
 
      07-22-2006
Dave,

Sometimes generating classes from .ini or XML files is not the best
way. You are just translating one language into another and are making
bigger headaches for your self. It is certainly cool and bragable to
say that "my classes get generated on the fly from XML" but Python is
terse and reasonable enough to just write it in Python. In other words
instead of saying <turbine> <power>2MW</power></turbine> just write
some Python code that instantiates a turbine with a 2MW power based on
your class. Then you can evaluate Python code in Python and you even
got your on-the-fly generation.
As a general rule, I would say to think 3 times before touching XML in
Python unless you are absolutely forced to. Config .ini files can be
more acceptable but Python is still best. Why write
;;My turbine class
[turbine]
power=2MW
speed=800rpm
....
when you can just say:
#my turbine class
t=Turbine( power="2MW", \
speed="800rpm", \
...
First case is a little shorter but then you have to use a parser for it
while in the second case you just execute the file, and besides, you
can edit it with any Python editor.

Hope this helps,
Nick V.


(E-Mail Removed) wrote:
> Hi
>
> > Also, I gave the example using Python code as 'config' format, but any
> > structured enough text format could do, ie JSON, XML, or even ini-like:
> >
> > # schema.ini
> > objects = turbine1, frobnicator2
> >
> > [turbine1]
> > class=Turbine
> > upstream=frobnicator2
> > downstream=
> >

>
> yes, I like the idea of using .ini type file format or XML, very much.
> There are parser available which will automatically building python
> objects from this, won't they (like configparser)? I'll have to get
> reading over the weekend...
>
> > >>def get_class_by_name(name):
> > >> return globals()[name]
> > >

> >
> > Q&D way to retrieve the class object (Python's classes are themselves
> > objects) known by it's name (as a string).

>
> ok, so it actually returns the class object itself.
> One thing that confuses me is that objects have a name (self.name) but
> object instances also have a name (e.g. myspecialturbine = turbine(...)
> ---- how do I discover the name 'myspecialturbine' ?). And object
> instances have a class name too ('turbine'). Aaargh, too many names!
> what if just want to know what the name of the instance is (in this
> case 'myspecialturbine'?)
>
> Right. I'll have a go at pulling all this together over the weekend
> hopefully. Hurrah! Thanks for all the help, to everyone.
> Dave


 
Reply With Quote
 
Patrick Maupin
Guest
Posts: n/a
 
      07-23-2006

(E-Mail Removed) wrote:
> I have a problem. I'm writing a simulation program with a number of
> mechanical components represented as objects. When I create instances
> of objects, I need to reference (link) each object to the objects
> upstream and downstream of it, i.e.
>
> supply = supply()
> compressor = compressor(downstream=combustor, upstream=supply)
> combuster = combuster(downstream=turbine, upstream=compressor)
> etc.
>
> the problem with this is that I reference 'combustor' before is it
> created. If I swap the 2nd and 3rd lines I get the same problem
> (compressor is referenced before creation).
>
>
> aargh!!! any ideas on getting around this?
>
> Dave


I have done similar things in the past. One useful trick is to define
a special class for connections, create a single instance of this
class, and make all your connections as attributes of this instance.
For example:

world = Simulation()

world.supply = Supply()
world.compressor = Compressor(downstream=world.cumbustor,
upstream=world.supply)
world.cumbuster = Combuster(downstream=world.turbine,
upstream=world.compressor)

Because Python lets you control attribute access to your simulation
world object, it is relatively easy to make proxy objects for
attributes which don't yet exist via __getattr__, and then to insert
the real object into the proxy via __setattr__.

Alternatively, the script (using the same syntax as shown above!) can
simply collect all the connection information when it is run, then make
a "real" structure later. This works best if your simulation objects
(Supply, Compressor, Cumbuster) allow setting of the connection
attributes after instantiation.

Regards,
Pat

 
Reply With Quote
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      07-24-2006
Nick Vatamaniuc wrote:
> Dave,
>
> Sometimes generating classes from .ini or XML files is not the best
> way. You are just translating one language into another and are making
> bigger headaches for your self. It is certainly cool and bragable to
> say that "my classes get generated on the fly from XML" but Python is
> terse and reasonable enough to just write it in Python. In other words
> instead of saying <turbine> <power>2MW</power></turbine> just write
> some Python code that instantiates a turbine with a 2MW power based on
> your class. Then you can evaluate Python code in Python and you even
> got your on-the-fly generation.
> As a general rule, I would say to think 3 times before touching XML in
> Python unless you are absolutely forced to. Config .ini files can be
> more acceptable but Python is still best. Why write
> ;;My turbine class
> [turbine]
> power=2MW
> speed=800rpm
> ...
> when you can just say:
> #my turbine class
> t=Turbine( power="2MW", \
> speed="800rpm", \
> ...
> First case is a little shorter but then you have to use a parser for it


There's one builtin.

> while in the second case you just execute the file, and besides, you
> can edit it with any Python editor.
>


This is certainly nice when the users are able to write python code, but
that's not always the case. Also, it can be dangerous to directly
execute user's python code...


--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '(E-Mail Removed)'.split('@')])"
 
Reply With Quote
 
davehowey@f2s.com
Guest
Posts: n/a
 
      07-24-2006
> > First case is a little shorter but then you have to use a parser for it
>
> There's one builtin.


do you mean 'configparser'? I'm just trying to figure out how this
works. Does it generate objects from the config file automatically?

Dave

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
using identifiers before they are defined Julio Sergio Python 0 06-12-2012 05:53 PM
Using parenthesis with defined (#if defined(...)) Angel Tsankov C++ 1 04-05-2006 10:00 PM
#if (defined(__STDC__) && !defined(NO_PROTOTYPE)) || defined(__cplusplus) Oodini C Programming 1 09-27-2005 07:58 PM
WSDL- Mapping Application Defined Names to XML Names Craig XML 0 02-09-2004 04:14 PM
XSL rules applying to XSD (XML schema) defined type names (as opposed to node names) Lewis G. Pringle, Jr. XML 0 09-30-2003 10:34 PM



Advertisments