On Mon, Dec 14, 2020 at 01:09:56AM +0300, Paul Sokolovsky wrote:
Do you think there can be difference between the following two expressions:
obj.meth() (obj.meth)()
?
Okay, I'll bite. Of course there is a difference: the first statement is ten characters long, the second is 12 characters long. Are you asking for a semantic difference (the two statements do something different) or an implementation difference (the two statements do the same thing in slightly different ways)? Implementation differences are fairly boring (to me): it might happen to be that some Python interpreters happen to compile the first statement into a slightly different set of byte codes to the second. I don't care too much about that, unless there are large performance (speed or memory) differences. For what it is worth, Python 1.5 generates the exact same byte code for both expressions; so does Python 3.9. However the byte code for 1.5 and for 3.9 are different. However, the semantics of the two expressions are more or less identical in all versions of Python, regardless of the byte-code used. (I say "more or less" because there may be subtle differences between versions, relating to the descriptor protocol, or lack there of, old and new style classes, attribute lookup, and handling of unbound methods.) [...]
The question is definitely with a trick (why else there would be the intro), and first answer which comes to mind might not be the right one. As a hint, to try to get a grounded answer to that question, it would be useful to look at the difference in disassembly of the above code in CPython3.6 vs CPython3.7 (or later):
python3.6 -m dis meth_call.py python3.7 -m dis meth_call.py
Then, to try to explain the difference at the suitable level of abstraction.
At a suitable level of abstraction, there is no difference. The suitable level of abstraction is at the level of the Python execution model, where `(expression)` and `expression` mean the same, where the brackets are used for grouping.
it might be helpful to add the 3rd line:
t = obj.meth; t()
That clearly has different semantics from the first two: it has the side-effect of binding a value to the name t. I'm not sure where you think this question is going to lead us. Wherever it is, I wish you would get to the point. Are you suggesting that we give a *semantic* difference to: ( expression ) compared to the unbracketed `expression`? -- Steve