Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Create object from variable indirect reference?

338 views
Skip to first unread message

NickC

unread,
Nov 10, 2009, 8:29:25 PM11/10/09
to

I can't seem to find a way to do something that seems straighforward, so I
must have a mental block. I want to reference an object indirectly
through a variable's value.

Using a library that returns all sorts of information about "something", I
want to provide the name of the "something" via a variable (command line
argument). The something is a class in the library and I want to
instantiate an object of the class so I can start querying it. I can't
figure out how to pass the name of the class to the library.

Or, put another way, I can't figure out how to indirectly reference the
value of the command line argument to create the object.

To make it clearer, it's roughly equivalent to this in bash:
Sun="1AU" ; body=Sun; echo ${!body} --> outputs "1AU".

command line:
$ ./ephemeris.py Moon

code:
import ephem
import optparse

# various option parsing (left out for brevity),
# so variable options.body contains string "Moon",
# or even "Moon()" if that would make it easier.

# Want to instantiate an object of class Moon.
# Direct way:
moon1 = ephem.Moon()
# Indirect way from command line with a quasi bashism that obviously fails:
moon2 = ephem.${!options.body}()

Can someone point me in the right direction here?

(The library is PyEphem, an extraordinarily useful library for anyone
interested in astronomy.)

Many thanks,

--
NickC

Jon Clements

unread,
Nov 10, 2009, 8:38:47 PM11/10/09
to

A direct way is to use:

moon1 = getattr(ephem, 'Moon')()

hth
Jon.

Rami Chowdhury

unread,
Nov 10, 2009, 8:43:54 PM11/10/09
to Nick, pytho...@python.org
On Tue, 10 Nov 2009 06:59:25 -0800, NickC <repl...@works.fine.invalid>
wrote:

Since Python 'variables' are really keys in a namespace dictionary, it's
fairly straightforward to get at them given a string value -- what you
probably want in this case is the built-in function getattr()
(http://www.diveintopython.org/power_of_introspection/getattr.html)...

So getattr(ephem, "Moon") should give you the class object ephem.Moon,
which you can then instantiate...

--
Rami Chowdhury
"Never attribute to malice that which can be attributed to stupidity" --
Hanlon's Razor
408-597-7068 (US) / 07875-841-046 (UK) / 0189-245544 (BD)

NickC

unread,
Nov 10, 2009, 9:33:17 PM11/10/09
to

Many thanks for the replies. getattr() works great:

>>> name='Moon'
>>> m2 = getattr(ephem,name)()
>>> m2.compute(home)
>>> print ephem.localtime(m2.rise_time)
2009-11-11 01:30:36.000002

shows the moon will rise at 1:30am localtime tonight at my home location.

Excellent.

--
NickC

Hrvoje Niksic

unread,
Nov 10, 2009, 9:16:34 PM11/10/09
to
NickC <repl...@works.fine.invalid> writes:

> moon2 = ephem.${!options.body}()

moon2 = getattr(ephem, options.body)()

jhermann

unread,
Nov 17, 2009, 2:56:00 PM11/17/09
to
On 10 Nov., 17:03, NickC <reply...@works.fine.invalid> wrote:
> Many thanks for the replies.  getattr() works great:

You can get a little more versatile and even specify the location of
the name (i.e. the module / package name) without pre-importing it,
like this...

def importName(modulename, name=None):
""" Import identifier C{name} from module C{modulename}.

If name is omitted, modulename must contain the name after the
module path, delimited by a colon.

@param modulename: Fully qualified module name, e.g. C{x.y.z}.
@param name: Name to import from C{modulename}.
@return: Requested object.
@rtype: object
"""
if name is None:
modulename, name = modulename.split(':', 1)
module = __import__(modulename, globals(), {}, [name])
return getattr(module, name)

print importName("socket:gethostname")()


This is especially useful if you want to specify factory classes or
the like in a non-python config file. The syntax is the same as that
of setuptools entry points.

0 new messages