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

method to intercept string formatting % operations

0 views
Skip to first unread message

bradallen

unread,
Feb 5, 2010, 9:57:18 AM2/5/10
to
Hello,

For container class derived from namedtuple, but which also behaves
like a dictionary by implementing __getitem__ for non-integer index
values, is there a special reserved method which allows intercepting %
string formatting operations? I would like for my container type to
behave appropriately depending on whether the string formatting
operation has a string like this :

"whatever %s yadayada" % mycontainer # needs to act like a tuple

"whatever %(key)s yadayada" % mycontainer # needs to act like a
dictionary

I looked through the Python data model docs at <http://docs.python.org/
reference/datamodel.html#emulating-container-types> but only found
this:

"If the left operand of a % operator is a string or Unicode object, no
coercion takes place and the string formatting operation is invoked
instead."

Thanks!

Jean-Michel Pichavant

unread,
Feb 5, 2010, 10:49:00 AM2/5/10
to bradallen, pytho...@python.org
class toto:
def __getitem__(self, key):
return 'paf'
def __str__(self):
return 'pif'
def toTuple(self):
return (1,2,3)


1/ print '%s %s %s' % toto().toTuple()
'1 2 3'
2/ print '%(key)s ' % toto()
'paf'
3/ print '%s' % toto()
'pif'


1/ I don't know how to spare the explicit toTuple conversion, supporting
tuple() would be tedious
2/ thanks to __getitem__ (duck typing)
3/ thanks to __str__

Anyway why would you want to use the tuple form ? it's beaten in every
aspect by the dictionary form.


JM

"If you need something call me, I'll tell you how to live without it"
(Coluche, about politicians)

Brad Allen

unread,
Feb 5, 2010, 12:48:24 PM2/5/10
to Jean-Michel Pichavant, pytho...@python.org
On Fri, Feb 5, 2010 at 9:49 AM, Jean-Michel Pichavant
<jeanm...@sequans.com> wrote:

> Anyway why would you want to use the tuple form ? it's beaten in every
> aspect by the dictionary form.

I'm subclassing a namedtuple, and adding some additional functionality
such as __getitem__, __setitem__, so that the namedtuple also behaves
like a dict.

Raymond Hettinger

unread,
Feb 5, 2010, 3:53:51 PM2/5/10
to
On Feb 5, 6:57 am, bradallen <bradallen...@gmail.com> wrote:
> Hello,
>
> For container class derived from namedtuple, but which also behaves
> like a dictionary by implementing __getitem__ for non-integer index
> values, is there a special reserved method which allows intercepting %
> string formatting operations? I would like for my container type to
> behave appropriately depending on whether the string formatting
> operation has a string like this :
>
> "whatever %s yadayada" % mycontainer  # needs to act like a tuple
>
> "whatever %(key)s yadayada" % mycontainer  # needs to act like a
> dictionary


The implementation for str.__mod__ refuses to
treat tuples and tuple subclasses as a dictionary.
Since namedtuples are a subclass of tuple, you're
not going to have any luck with this one.

To see actual C code, look at PyString_Format() in
http://svn.python.org/view/python/trunk/Objects/stringobject.c?view=markup

PyObject *dict = NULL;
. . .
if (Py_TYPE(args)->tp_as_mapping && !PyTuple_Check(args) &&
!PyObject_TypeCheck(args, &PyBaseString_Type))
dict = args;

Since automatic conversion is out, you can instead use
the namedtuple._asdict() method for an explicit conversion:

>>> from collections import namedtuple
>>> Point = namedtuple('Point', 'x y')
>>> p = Point(5, 12)
>>> 'x: %(x)s' % p._asdict()
'x: 5'


Raymond

Steven D'Aprano

unread,
Feb 5, 2010, 5:19:31 PM2/5/10
to
On Fri, 05 Feb 2010 16:49:00 +0100, Jean-Michel Pichavant wrote:

> Anyway why would you want to use the tuple form ? it's beaten in every
> aspect by the dictionary form.

Except convenience, efficiency and readability.

"%s %s" % (1, 2)

versus

"%(a)s %(b)s" % {'a': 1, 'b': 2}


I'm all in favour of the second form when you need it. But you certainly
don't need it all time.

--
Steven

0 new messages