2

How do I forcefully create a new object (in this case a dictionary) in python? The following should explain my problem:

>>> class A():
...   def __init__(self, a={}):
...     self.a=a
... 
>>> id(A().a) == id(A().a)
True

>>> class A():
...   def __init__(self, a=dict()):
...     self.a=a
... 
>>> id(A().a) == id(A().a)
True

>>> class A():
...   def __init__(self, a={}):
...     self.a=copy.deepcopy(a)
... 
>>> id(A().a) == id(A().a)
False

As you can see, the first two methods give me a pointer to the same empty dictionary, which means if I modify the dictionary in one object, it gets modified in the other. The third method seems so "unclean" to me. Is there an alternative? I know I could also use copy.copy, but I prefer deepcopy, for exactly these reasons.

pidgey
  • 245
  • 1
  • 3
  • 15
  • 1
    Related reading: [“Least Astonishment” in Python: The Mutable Default Argument](http://stackoverflow.com/q/1132941/953482) – Kevin Aug 18 '16 at 13:40
  • By the way, `id(A().a) == id(A().a)` is better written as `A().a is A().a` – mgilson Aug 18 '16 at 13:42
  • I was debugging this visually with id(), that's why I used it. But you're right, it's more pythonic indeed. Will keep that in mind next time I post, thanks – pidgey Aug 18 '16 at 13:46

1 Answers1

2

Here is a common idiom:

def __init__(self, a=None):
  if a is None:
    a = {}
  ...
NPE
  • 486,780
  • 108
  • 951
  • 1,012