A instance of your Book class can only have one attribute called pages. That attribute can be anything (an integer, a callable function, anything really), but it can only be one thing.
Another way of viewing things is at the byte-code level - given two lines of code:
>>> def a():
... book.pages
... book.pages()
...
Here is what it disassembles:
>>> dis.dis(a)
2 0 LOAD_GLOBAL 0 (book)
3 LOAD_ATTR 1 (pages)
6 POP_TOP
3 7 LOAD_GLOBAL 2 (book)
10 LOAD_ATTR 1 (pages)
13 CALL_FUNCTION 0
[...a few more irrelevant lines...]
The first line (book.pages) loads the book object, and from that loads the pages attribute (LOAD_ATTR)
The second line (book.pages()) does the exact same thing, loads the book object, loads the pages attribute, then calls the CALL_FUNCTION attribute.
There is no sane way you can make the LOAD_ATTR return something different based on how it will eventually be used. The closest you can get is to return a weird object which acts like both
>>> class WeirdInteger(int):
... def __call__(self, including_toc):
... print "WeirdInteger(%s) called" % (self)
...
>>> a = WeirdInteger(10)
>>> a
10
>>> a*2
20
>>> a()
WeirdInteger(10) called
..but, don't do that. No one using you code will expect the pages attribute to work like this, and bits of code the pages will be passed to might require an actual integer.
Instead design your Books