0
class X:
    def __init__(self, d={}):
        self.x = []
        d['any'] = self.x

    def append(self, i):
        self.x.append(i)

x = X()
x.append(3)
x.append(13)
x.append(123213)
print(x.x)  # show [3, 13, 123213]

The question is, what happens to d? Is it garbage collected? If it is, how does x still exist?

hans-t
  • 3,093
  • 8
  • 33
  • 39
  • 2
    Why would `d` be garbage collected? You still have `x` and `X` and `X.__init__` in memory. `x` references `X`, and `X` references `__init__` and that function references `d`. – Martijn Pieters Oct 23 '15 at 14:00
  • 2
    Also the `x` instance references `x.x`, the list, so there is no reason for *that* list to be garbage collected. `x.x` does not reference `d`, that relationship goes the other way. – Martijn Pieters Oct 23 '15 at 14:01
  • Is it possible to refer to `d` then? – hans-t Oct 23 '15 at 14:02
  • Last but not least, `d` is a *function default* and stored in the function object. – Martijn Pieters Oct 23 '15 at 14:02
  • Yes, you can reference `X.x.__defaults__` – Martijn Pieters Oct 23 '15 at 14:02
  • Regardless of whether or not `d` was done, that would just reduce the reference count of the variables it reverse to, like `x` in this case. Only when a variable's reference count is 0 is it available for garbage collection – Eric Renouf Oct 23 '15 at 14:02
  • 1
    Don't do this. Never use mutable types as the defaults. Every instance of class `X` will share the same `d` dict. – TheBlackCat Oct 23 '15 at 14:04
  • 1
    @TheBlackCat Never say never. A mutable type as a default value is perfectly valid, *if* you know that you want to accumulate values across function calls. The trick is knowing when it is appropriate. – chepner Oct 23 '15 at 14:07

1 Answers1

3

By d, you really mean the dict object that serves as the default value for that parameter. There is a "hidden" reference to this dict that prevents it from being garbage collected.

>>> print x.__init__.__defaults__
({'any': [3, 13, 123213]},)
hans-t
  • 3,093
  • 8
  • 33
  • 39
chepner
  • 497,756
  • 71
  • 530
  • 681