<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Greg Ewing wrote:
<blockquote cite="mid43FBB1D5.4040309@canterbury.ac.nz" type="cite">
  <pre wrap="">Fuzzyman wrote:

  </pre>
  <blockquote type="cite">
    <pre wrap="">I've had problems in code that needs to treat strings, lists and
dictionaries differently (assigning values to a container where all
three need different handling) and telling the difference but allowing
duck typing is *problematic*.
    </pre>
  </blockquote>
  <pre wrap=""><!---->
You need to rethink your design so that you don't
have to make that kind of distinction.</pre>
</blockquote>
<br>
Well... to *briefly* explain the use case, it's for value assignment in
ConfigObj.<br>
<br>
It basically accepts as valid values strings and lists of strings [#]_.
You can also create new subsections by assigning a dictionary.<br>
<br>
It needs to be able to recognise lists in order to check each list
member is a string. (See note below, it still needs to be able to
recognise lists when writing, even if it is not doing type checking on
assignment.)<br>
<br>
It needs to be able to recognise dictionaries in order to create a new
section instance (rather than directly assigning the dictionary).<br>
<br>
This is *terribly* convenient for the user (trivial example of creating
a new config file programatically) :<br>
<br>
from configobj import ConfigObj<br>
cfg = ConfigObj(newfilename)<br>
cfg['key'] = 'value'<br>
cfg['key2'] = ['value1', 'value2', 'value3']<br>
cfg['section'] = {'key': 'value', 'key2': ['value1', 'value2',
'value3']}<br>
cfg.write()<br>
<br>
Writes out :<br>
<br>
key = value<br>
key2 = value1, value2, value3<br>
[section]<br>
key = value<br>
key2 = value1, value2, value3<br>
<br>
(Note none of those values needed quoting, so they aren't.)<br>
<br>
Obviously I could force the creation of sections and the assignment of
list values to use separate methods, but it's much less readable and
unnecessary.<br>
<br>
The code as is works and has a nice API. It still needs to be able to
tell what *type* of value is being assigned.<br>
<br>
Mapping and sequence protocols are so loosely defined that in order to
support 'list like objects' and 'dictionary like objects' some
arbitrary decision about what methods they should support has to be
made. (For example a read only mapping container is unlikely to
implement __setitem__ or methods like update).<br>
<br>
At first we defined a mapping object as one that defines __getitem__
and keys (not update as&nbsp; I previously said), and list like objects as
ones that define __getitem__ and *not* keys. For strings we required a
basestring subclass. In the end I think we ripped this out and just
settled on isinstance tests.<br>
<br>
All the best,<br>
<br>
Michael Foord<br>
<br>
<br>
.. [#] Although it has two modes. In the 'default' mode you can assign
any object as a value and a string representation is written out. A
more strict mode checks values at the point you assign&nbsp; them - so
errors will be raised at that point rather than propagating into the
config file. When writing you still need to able to recognise lists
because each element is properly quoted.<br>
</body>
</html>