<!DOCTYPE html PUBLIC
"-//W3C//DTD HTML 4.0 Transitional//EN">
<link rel=
"STYLESHEET" href=
"lib.css" type='text/css'
/>
<link rel=
"SHORTCUT ICON" href=
"../icons/pyfav.png" type=
"image/png" />
<link rel='start' href='../index.html' title='Python Documentation Index'
/>
<link rel=
"first" href=
"lib.html" title='Python Library Reference'
/>
<link rel='contents' href='contents.html'
title=
"Contents" />
<link rel='index' href='genindex.html' title='Index'
/>
<link rel='last' href='about.html' title='About this document...'
/>
<link rel='help' href='about.html' title='About this document...'
/>
<link rel=
"next" href=
"optparse-other-reasons-to-extend-optparse.html" />
<link rel=
"prev" href=
"optparse-adding-new-types.html" />
<link rel=
"parent" href=
"optparse-extending-optparse.html" />
<link rel=
"next" href=
"optparse-other-reasons-to-extend-optparse.html" />
<meta name='aesop' content='information'
/>
<title>6.21.5.2 Adding new actions
</title>
<div id='top-navigation-panel' xml:id='top-navigation-panel'
>
<table align=
"center" width=
"100%" cellpadding=
"0" cellspacing=
"2">
<td class='online-navigation'
><a rel=
"prev" title=
"6.21.5.1 Adding new types"
href=
"optparse-adding-new-types.html"><img src='../icons/previous.png'
border='
0' height='
32' alt='Previous Page' width='
32'
/></A></td>
<td class='online-navigation'
><a rel=
"parent" title=
"6.21.5 Extending optparse"
href=
"optparse-extending-optparse.html"><img src='../icons/up.png'
border='
0' height='
32' alt='Up One Level' width='
32'
/></A></td>
<td class='online-navigation'
><a rel=
"next" title=
"6.21.5.3 Other reasons to"
href=
"optparse-other-reasons-to-extend-optparse.html"><img src='../icons/next.png'
border='
0' height='
32' alt='Next Page' width='
32'
/></A></td>
<td align=
"center" width=
"100%">Python Library Reference
</td>
<td class='online-navigation'
><a rel=
"contents" title=
"Table of Contents"
href=
"contents.html"><img src='../icons/contents.png'
border='
0' height='
32' alt='Contents' width='
32'
/></A></td>
<td class='online-navigation'
><a href=
"modindex.html" title=
"Module Index"><img src='../icons/modules.png'
border='
0' height='
32' alt='Module Index' width='
32'
/></a></td>
<td class='online-navigation'
><a rel=
"index" title=
"Index"
href=
"genindex.html"><img src='../icons/index.png'
border='
0' height='
32' alt='Index' width='
32'
/></A></td>
<div class='online-navigation'
>
<b class=
"navlabel">Previous:
</b>
<a class=
"sectref" rel=
"prev" href=
"optparse-adding-new-types.html">6.21.5.1 Adding new types
</A>
<b class=
"navlabel">Up:
</b>
<a class=
"sectref" rel=
"parent" href=
"optparse-extending-optparse.html">6.21.5 Extending optparse
</A>
<b class=
"navlabel">Next:
</b>
<a class=
"sectref" rel=
"next" href=
"optparse-other-reasons-to-extend-optparse.html">6.21.5.3 Other reasons to
</A>
<!--End of Navigation Panel-->
<H3><A NAME=
"SECTION0082152000000000000000"></A><A NAME=
"optparse-adding-new-actions"></A>
6.21.5.2 Adding new actions
Adding new actions is a bit trickier, because you have to understand
that
<tt class=
"module">optparse
</tt> has a couple of classifications for actions:
<DT><STRONG>``store'' actions
</STRONG></DT>
<DD>actions that result in
<tt class=
"module">optparse
</tt> storing a value to an attribute of the
current OptionValues instance; these options require a
<tt class=
"member">dest
</tt>
attribute to be supplied to the Option constructor
<DT><STRONG>``typed'' actions
</STRONG></DT>
<DD>actions that take a value from the command line and expect it to be
of a certain type; or rather, a string that can be converted to a
certain type. These options require a
<tt class=
"member">type
</tt> attribute to the
These are overlapping sets: some default ``store'' actions are
<code>store
</code>,
<code>store_const
</code>,
<code>append
</code>, and
<code>count
</code>, while the default ``typed''
actions are
<code>store
</code>,
<code>append
</code>, and
<code>callback
</code>.
When you add an action, you need to decide if it's a ``store'' action, a
``typed'' action, neither, or both. Three class attributes of
Option (or your Option subclass) control this:
<DT><STRONG><tt class=
"member">ACTIONS
</tt></STRONG></DT>
<DD>all actions must be listed in ACTIONS
<DT><STRONG><tt class=
"member">STORE_ACTIONS
</tt></STRONG></DT>
<DD>``store'' actions are additionally listed here
<DT><STRONG><tt class=
"member">TYPED_ACTIONS
</tt></STRONG></DT>
<DD>``typed'' actions are additionally listed here
In order to actually implement your new action, you must override
Option's
<tt class=
"method">take_action()
</tt> method and add a case that recognizes your
For example, let's add an
<code>extend
</code> action. This is similar to the
standard
<code>append
</code> action, but instead of taking a single value from
the command-line and appending it to an existing list,
<code>extend
</code> will
take multiple values in a single comma-delimited string, and extend an
existing list with them. That is, if
<code>"-names"</code> is an
<code>extend
</code>
option of type
<code>string
</code>, the command line
<div class=
"verbatim"><pre>
--names=foo,bar --names blah --names ding,dong
<div class=
"verbatim"><pre>
[
"foo",
"bar",
"blah",
"ding",
"dong"]
Again we define a subclass of Option:
<div class=
"verbatim"><pre>
ACTIONS = Option.ACTIONS + (
"extend",)
STORE_ACTIONS = Option.STORE_ACTIONS + (
"extend",)
TYPED_ACTIONS = Option.TYPED_ACTIONS + (
"extend",)
def take_action(self, action, dest, opt, value, values, parser):
lvalue = value.split(
",")
values.ensure_value(dest, []).extend(lvalue)
self, action, dest, opt, value, values, parser)
<code>extend
</code> both expects a value on the command-line and stores that
value somewhere, so it goes in both
<tt class=
"member">STORE_ACTIONS
</tt> and
<tt class=
"member">TYPED_ACTIONS
</tt>
<tt class=
"method">MyOption.take_action()
</tt> implements just this one new action, and
passes control back to
<tt class=
"method">Option.take_action()
</tt> for the standard
<tt class=
"module">optparse
</tt> actions
<code>values
</code> is an instance of the optparse_parser.Values class,
which provides the very useful
<tt class=
"method">ensure_value()
</tt> method.
<tt class=
"method">ensure_value()
</tt> is essentially
<tt class=
"function">getattr()
</tt> with a safety valve;
<div class=
"verbatim"><pre>
values.ensure_value(attr, value)
If the
<code>attr
</code> attribute of
<code>values
</code> doesn't exist or is None, then
ensure_value() first sets it to
<code>value
</code>, and then returns 'value.
This is very handy for actions like
<code>extend
</code>,
<code>append
</code>, and
<code>count
</code>, all of which accumulate data in a variable and expect that
variable to be of a certain type (a list for the first two, an integer
for the latter). Using
<tt class=
"method">ensure_value()
</tt> means that scripts using
your action don't have to worry about setting a default value for the
option destinations in question; they can just leave the default as
None and
<tt class=
"method">ensure_value()
</tt> will take care of getting it right when
<div class='online-navigation'
>
<table align=
"center" width=
"100%" cellpadding=
"0" cellspacing=
"2">
<td class='online-navigation'
><a rel=
"prev" title=
"6.21.5.1 Adding new types"
href=
"optparse-adding-new-types.html"><img src='../icons/previous.png'
border='
0' height='
32' alt='Previous Page' width='
32'
/></A></td>
<td class='online-navigation'
><a rel=
"parent" title=
"6.21.5 Extending optparse"
href=
"optparse-extending-optparse.html"><img src='../icons/up.png'
border='
0' height='
32' alt='Up One Level' width='
32'
/></A></td>
<td class='online-navigation'
><a rel=
"next" title=
"6.21.5.3 Other reasons to"
href=
"optparse-other-reasons-to-extend-optparse.html"><img src='../icons/next.png'
border='
0' height='
32' alt='Next Page' width='
32'
/></A></td>
<td align=
"center" width=
"100%">Python Library Reference
</td>
<td class='online-navigation'
><a rel=
"contents" title=
"Table of Contents"
href=
"contents.html"><img src='../icons/contents.png'
border='
0' height='
32' alt='Contents' width='
32'
/></A></td>
<td class='online-navigation'
><a href=
"modindex.html" title=
"Module Index"><img src='../icons/modules.png'
border='
0' height='
32' alt='Module Index' width='
32'
/></a></td>
<td class='online-navigation'
><a rel=
"index" title=
"Index"
href=
"genindex.html"><img src='../icons/index.png'
border='
0' height='
32' alt='Index' width='
32'
/></A></td>
<div class='online-navigation'
>
<b class=
"navlabel">Previous:
</b>
<a class=
"sectref" rel=
"prev" href=
"optparse-adding-new-types.html">6.21.5.1 Adding new types
</A>
<b class=
"navlabel">Up:
</b>
<a class=
"sectref" rel=
"parent" href=
"optparse-extending-optparse.html">6.21.5 Extending optparse
</A>
<b class=
"navlabel">Next:
</b>
<a class=
"sectref" rel=
"next" href=
"optparse-other-reasons-to-extend-optparse.html">6.21.5.3 Other reasons to
</A>
<span class=
"release-info">Release
2.4.2, documentation updated on
28 September
2005.
</span>
<!--End of Navigation Panel-->
See
<i><a href=
"about.html">About this document...
</a></i> for information on suggesting changes.