[Python-3000] Nix dict.copy()

VanL van.lindberg at gmail.com
Thu Feb 14 16:13:22 CET 2008


Daniel Stutzbach wrote:
> Okay, but turn it around for a minute.  Which types should have a 
> .copy() method and why?

I would argue that it's not about mappings, it's about mutability. I 
always thought the .copy method on dicts was to allow functions to work 
on a passed-in dict without causing spooky action at a distance due to 
mutability issues. (See the silly example at the end of the post.) Sets, 
being by default mutable, got the same treatment.

Other types (other than lists) aren't susceptible to this sort of 
problem. The default idiom for lists,  copy = list[:], is a workaround 
for the lack of a .copy() method.

I would argue that if you want to make some sort of ABC, make it a 
'Mutable' ABC and put the .copy method in *there*. \

- Van

*For example, you can get into this problem when using dicts for string 
substitution:

def fragment1(vars, boilerplate=''):
    if boilerplate: vars['extra'] = boilerplate
    return "%(sentence)s with %(something)s %(extra)s." % vars

def fragment2(vars, boilerplate=''):
    if boilerplate: vars['extra'] = boilerplate
    return "%(another)s %(sentence)s with %(extra)s." % vars

def statement():
    # vars is a dict built from a database query
    vars = get_dict_from_db()
    return '%s %s' % (fragment1(vars, 'extra'), fragment2(vars))

Because of mutability, the 'extra' in fragment1 will also show up in 
fragment2. The solution to this is to make a .copy(). The susceptibility 
of newbies to this 'spooky action at a distance' problem is one of the 
reasons why mutability and immutability have to be addressed almost at 
the very start of many learning Python books.







More information about the Python-3000 mailing list