0

Why defining a default list for a class method's parameter makes it shared across instances?

Does that mean that this list param, in the following example it is props, got declared as a class attribute instead of an instance attribute?

And if so, does that mean that all the class method's params got defined as class attributes? and if so, why setting the name by appending a text string does not produce the same issue?


Example

Given the following example

class Node():
    def __init__(self, name="", props=[]):
        self.name = name
        self.props = props

    def __str__(self):
        return f"{self.name:<10} : props [{self._joined_props()}]"

    def AddProp(self, ptext):
        self.props.append(ptext)

    def AppendName(self, nodename):
        self.name += nodename

    def _joined_props(self):
        return ", ".join(self.props) 

node1 = Node()
node1.AppendName("node1")
node1.AddProp("p1")

node2 = Node()
node2.AppendName("node2")
node2.AddProp("p2")

print(node1)
print(node2)

outputs

node1      : props [p1, p2]
node2      : props [p1, p2]

Changing the __init__() to be

    def __init__(self, name="", props=[]):
        self.name = name
        # self.props = props # old
        self.props = []      # new

outputs the expected result

node1      : props [p1]
node2      : props [p2]

For a more realistic example, follow the Node class in the tree data structure demo defined @ weshouman\tut-py-tree:tree.py#L61

weshouman
  • 632
  • 9
  • 17
  • 1
    "Why defining a default list for a class method's parameter makes it shared across instances?" Defining a mutable argument in _any_ parameter list makes it shared across invocations of the function. See the linked duplicate. – AKX Aug 31 '22 at 13:12
  • 1
    https://docs.python-guide.org/writing/gotchas/#what-actually-happens – Kai Diefenbach Aug 31 '22 at 13:20

0 Answers0