469,579 Members | 1,111 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,579 developers. It's quick & easy.

optparse object population

Say I have
class Header:
def __init__(self):
self.foo = 0
# ... more fields

and I have some commandline options that can specify better values for things
in the header, such as foo. If I try the obvious (to me):
parser = optparse.OptionParser()
parser.add_option('--secret', type='string', dest='header', default=Header())
parser.add_option('--foo', type='int', dest='header.foo')
(options, args) = parser.parse_args()

when I run the program with "--foo 3", I'm sadly left with something like
this:
print options

<Values at 0xdeadbeef: {'header': <Header instance at 0xdeadbeef>,
'header.foo': 3}>

So when optparse first initializes the variables to None, it's creating a
'header.foo' that has nothing to do with header=Header(). Is there a way to
coerce optparse into populating an object for me? Yes, I could just do
something like this:
(options, args) = parser.parse_args()
header = Header()
header.foo = options.foo
# ... more population of header

but I'd rather just end up with options.header that I could then use somewhere
else.

Am I going to have any success with this, or am I just SOL?

Thanks.

-E
Jul 18 '05 #1
1 1880
Eric O. Angell wrote:
Is there a way to coerce optparse into populating an object for me?


If you are dealing with just one object you can provide a custom values
parameter:

<code>
import optparse

class Header(object):
def __init__(self):
self.foo = "default-foo"
self.bar = "default-bar"
def __str__(self):
values = ["%s=%r" % nv for nv in self.__dict__.items()]
return "%s(%s)" % (self.__class__.__name__, ", ".join(values))
__repr__ = __str__

p = optparse.OptionParser()
p.add_option("--foo")
p.add_option("--bar")
p.add_option("--baz")

header = Header()
options, args = p.parse_args(["--foo", "custom-foo", "--baz", "custom-baz"],
values=header)
print "options is header", options is header
# True
print "header", header
</code>

You can even expand that to work with nested objects, but it gets a little
messy and you are probably better off with Jeff Epler's approach here:

<code-continued>
# (insert above code here)

class Header2(Header):
def __setattr__(self, name, value):
if "." in name:
left, right = name.split(".", 1)
setattr(getattr(self, left), right, value)
else:
object.__setattr__(self, name, value)

header2 = Header2()
header2.nested = Header2() # I use the same class here because I'm
# lazy, not for technical reasons
p.add_option("--nested.foo")
options, args = p.parse_args(["--nested.foo", "hi there"], values=header2)
print options
</code-continued>

Especially, I have some doubts whether __setattr__("dotted.name", value)
will always be allowed.

Peter

Jul 18 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

7 posts views Thread by Henry Ludemann | last post: by
1 post views Thread by sector119 | last post: by
5 posts views Thread by Sébastien Boisgérault | last post: by
3 posts views Thread by Karlo Lozovina | last post: by
2 posts views Thread by Tim Arnold | last post: by
7 posts views Thread by wannymahoots | last post: by
5 posts views Thread by RyanN | last post: by
1 post views Thread by John O'Hagan | last post: by
4 posts views Thread by guiromero | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.