An annoyance in Python's attribute access rules
When looking up names on objects, I really wish that Python had a special attribute accessor for looking up attributes it was about to call, instead of only running them through the regular attribute lookup chain.
While this uniformity probably has little effects on most
code, it complicates the life of things such as proxy objects that
trace and monitor access to objects, which sometimes want to behave
differently for 'var = you.foo
' than for 'var = you.foo()
'. You can
fake this by returning a proxied foo
object that has a __call__
method, but things can rapidly become complicated; for example, what
objects do you proxy this way and what objects do you return as is?
Unfortunately, changing this is one of those simple looking things
that strike to the heart of a language's conceptual model. Unless
you change Python's conceptual model of attribute access, a special
__getmethod__
accessor can only be a hack; it triggers only for
certain syntactic patterns of method calls, whereas the __call__
approach is fully general.
Sidebar: implementation complications
Adding such an attribute accessor would also have implementation
complications in the Python bytecode compiler and interpreter. Right
now, all object attributes are retrieved with a single bytecode
instruction, LOAD_ATTR
, and the LOAD_ATTR
that gets the function
object may be some distance from the actual calling of the function,
because the bytecode is stack based and puts the function arguments on
the top of the stack. The easiest way out would probably be to add a new
'load attribute to be called' instruction and make the compiler generate
it in the appropriate situation.
Comments on this page:
|
|