I have a function that works correctly when run from a debugger, but returns None
otherwise.
class HotelRoom(object):
def __init__(self, guestlst=[]):
self.guestlst = guestlst
def __repr__(self):
if self.guestlst == []:
self.guestlst.append("empty")
return 'HotelRoom(guestlst=%r)' % self.guestlst
def maybeFill(self, newGuests):
# return new guestlist on success; return None on failure
if self.guestlst == ["empty"]:
self.guestlst = newGuests
return self.guestlst
return None
if __name__ == "__main__":
h = HotelRoom()
print(h.maybeFill(["Nathan"]))
If I step through with a debugger, this works fine, and it has the expected output of ["Nathan"]
.
If I just run it, the output is None
.
Why does the function's output depend on whether it is being run in a debugger?
This happens because your __repr__
function changes the value it's supposed to be printing. When you're in the debugger, the act of the debugger trying to display the representation of the value to you changes that value, by changing []
to ['empty']
.
Because the maybeFill
function compares the list to ['empty']
, it returns false when the actual value is []
, which it always will be if repr()
was never called.
A less-surprising __repr__
will only display the value, but never change it. Consider, then, leaving the empty value as []
instead of ever transforming it to ['empty']
:
class HotelRoom(object):
def __init__(self, guestlst=[]):
self.guestlst = guestlst
def __str__(self):
if self.guestlst:
return 'Hotel room, with guests: %s' % ', '.join(self.guestlst)
return 'Empty hotel room'
def __repr__(self):
return 'HotelRoom(guestlst=%r)' % self.guestlst
def maybeFill(self, newGuests):
# return new guestlist on success; return None on failure
if self.guestlst == []:
self.guestlst = newGuests
return self.guestlst
return None
if __name__ == "__main__":
h = HotelRoom()
if h.maybeFill(["Nathan", "John"]) == None:
print("If you see this, the problem is not solved")
print(h)
As you can see in the online interpreter at https://ideone.com/drlN6w, the above works even when no debugger is causing __repr__
or __str__
to be called early.