I've run into a situation wherein an unused keyword argument in a class initialization leads to unwanted sharing of properties.
The ActionsAgent class below has a actions property that is intended to hold a list of pending actions, and a addActions method that appends actions to that list. Its initialization allows an initial action list to be supplied with a keyword argument that defaults to [].
###############
# Define
class ActionsAgent(object):
def __init__( self, name="",actions=[]):
self.name = name
# self.actions = []
self.actions = actions
print("init {}: {}".format(self.name,self.actions))
def addActions(self,*actions):
print("addActions {}, enter: {}".format(self.name,self.actions))
for action in actions:
self.actions.append(action)
print("addActions {}, exit: {}".format(self.name,self.actions))
The following test defines two agents, alice and bob, and adds two actions to each.
##############
# TEST
alice = ActionsAgent(name="alice")
bob = ActionsAgent(name="bob")
alice.addActions("hop", "skip")
bob.addActions( "run", "jump" )
print("alice end actions", alice.actions)
print("bob end actions", bob.actions)
The expected behavior is for alice's actions to be "hop" and "skip, and for bob's to be "run" and "jump". However upon running the test, it is shown that bob shares alice's actions when running addActions and that upon exit both agents share the same actions.
init alice: []
init bob: []
addActions alice, enter: []
addActions alice, exit: ['hop', 'skip']
addActions bob, enter: ['hop', 'skip']
addActions bob, exit: ['hop', 'skip', 'run', 'jump']
alice end actions ['hop', 'skip', 'run', 'jump']
bob end actions ['hop', 'skip', 'run', 'jump']
Note, that if the two agents are supplied the actions keyword (alice = ActionsAgent(name=alice,actions=[]), then the test run's as expected. If the initialization sets actions to [] the test also runs as expected.
What is going on here?