I am assuming that your main goal is to have pages
return a different value if a particular flag is set. One approach that might work, depending on your goal, would be to make pages
a property (in the precise Python sense) rather than an attribute. Then have it return a value with toc
or without, depending on whether a flag is set. So for example:
class Book(object):
def __init__(self, toc, pages):
self._toc = toc
self._pages = pages
self.include_toc = False
@property
def pages(self):
if self.include_toc:
return self._pages + self._toc
else:
return self._pages
Here's how it would work:
>>> b = Book(5, 55)
>>> b.pages
55
>>> b.include_toc = True
>>> b.pages
60
This doesn't do exactly what you've asked for, but it is as good or better for a certain subset of use cases (i.e. those in which you will be making multiple calls to pages
with the flag set, only changing the flag occasionally -- such as when include_toc
is set by an end user, or when a particular book should almost always or almost never include the _toc
in its page count.)
However, as phant0m points out, the flag is persistent, so this could generate unexpected results in some cases, if you set it and then fail to reset it when you're done. And as eryksun points out, a context manager is a classic solution to that problem.
While this may indeed be overengineering, it's so simple that I'll demonstrate it nonetheless. Simply add this to the definition of Book
:
@contextlib.contextmanager
def set_toc_reset(self, state):
try:
old_flag = self.include_toc
self.include_toc = state
yield self
finally:
self.include_toc = old_flag
This takes care of resetting the flag for you:
>>> from foo import Book
>>> b = Book(5, 55)
>>> with b.set_toc_reset(True):
... print b.pages
...
60
>>> b.include_toc
False