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?