3 ms·
It's easier if you look at the bytecode produced for the expression, which is: 1 0 LOAD_NAME 0 (foo) 2 LOAD_ATTR
by ubernostrum 9y ago
It's easier if you look at the bytecode produced for the expression, which is:
1 0 LOAD_NAME 0 (foo)
2 LOAD_ATTR 1 (bar)
4 LOAD_ATTR 2 (baz)
6 STORE_NAME 3 (a)
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
The CPython implementation is a stack-based virtual machine. The first instruction here, LOAD_NAME, pushes co_names['foo'] (basically, whatever 'foo' is bound to in local scope) to the top of the stack. That's at least one hash table lookup, since the scope is a hash table mapping names to values. Then LOAD_ATTR replaces the top-of-stack value with the value of its 'bar' attribute. That's another hash table lookup, since attributes are a hash table mapping names to values. Then another LOAD_ATTR to get to 'baz', that's another hash table lookup. Then STORE_NAME binds the value at the top of the stack to the name given as an argument ('a'). That's an insert or update of a hash table.
So, the expression 'a = foo.bar.baz' involves at least three hash table lookups and one insert or update.