On Tue, Dec 15, 2020 at 02:24:48PM +0300, Paul Sokolovsky wrote:
As I showed right in my first mail, in "a.b()", "a.b" doesn't get evaluated at all (since CPython3.7).
`a.b` still has to be looked up, even with the new fast LOAD_METHOD byte-code. The difference is that it may be able to avoid instantiating a MethodType object, since that would be immediately garbage-collected once the function object it wraps is called. The lookup still has to take place: ```
class Demo: ... def __getattribute__(self, name): ... if name == 'method': ... print("looked up method") ... return super().__getattribute__(name) ... def method(self): ... print("called method") ... obj = Demo() obj.method() looked up method called method
If the above example doesn't convince you that you are mistaken, how
about this?
class Demo2: ... def __getattr__(self, name): ... print("evaluating obj.%s" % name) ... return lambda: print("calling method") ... obj = Demo2() obj.method() evaluating obj.method calling method
In this second demonstration, obj.method *doesn't even exist* ahead of
time and has to be created dynamically on attribute lookup, before it
can be called.
--
Steve