[Python-ideas] Mitigating 'self.' Method Pollution
Steven D'Aprano
steve at pearwood.info
Sat Jul 11 03:34:13 CEST 2015
On Fri, Jul 10, 2015 at 07:28:14PM -0400, Joseph Jevnik wrote:
> How does this interact with descriptors, are they looked up everytime x and
> y are referenced or are they cached at the `this x, y` statement?
My understanding is that the actual execution of Python code does not
change. Today, if you write:
def method(self):
self.spam = self.eggs + 1
it compiles to something like this (in Python 2.7, different versions
may use different bytecode):
2 0 LOAD_FAST 0 (self)
3 LOAD_ATTR 0 (eggs)
6 LOAD_CONST 1 (1)
9 BINARY_ADD
10 LOAD_FAST 0 (self)
13 STORE_ATTR 1 (spam)
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
There's no caching of attribute look-ups, if spam or eggs are
descriptors (methods, properties, etc.) the descriptor protocol gets
called each time LOAD_ATTR or STORE_ATTR is called.
If you re-write that to:
def method(self):
self spam, eggs
spam = eggs + 1
it should compile to *exactly the same byte code*. It's just a compiler
directive, telling the compiler to treat any "spam" and "eggs" tokens as
if they were actually "self.spam" and "self.eggs".
That would, of course, mean that it's impossible to have a local
variable with the same name as the declared attribute. I often write
micro-optimized code like this:
spam = self.spam = {}
for x in big_loop:
# avoid the repeated look-ups of ".spam"
spam[x] = something
If I declared "self spam", this wouldn't work (or rather, it would work,
but it wouldn't have the effect I am looking for). The solution is
simple: don't declare "self spam" in this case.
--
Steve
More information about the Python-ideas
mailing list