Is there any way to have a property and a method with the same name? I mean a property that can be used the usual way and to be callable at the same time? Like this:
>>> b = Book()
>>> b.pages
123
>>> b.pages()
123
>>> b.pages(including_toc=False)
123
>>> b.pages(including_toc=True)
127
Python callable() Method The callable() method returns True if the object passed is callable, False if not. In Python, classes, methods, and instances are callable because calling a class returns a new instance. Instances are callable if their class includes __call__() method.
Definition and Usage The callable() function returns True if the specified object is callable, otherwise it returns False.
Python's functions are callable objects print("Hi", name) ... So, every function in Python is a callable, meaning it's an object that you're able to call.
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
class differently (maybe make pages
an regular function, or add a separate property for the pages_without_toc
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With