newbie: self.member syntax seems /really/ annoying
Michele Simionato
michele.simionato at gmail.com
Thu Sep 13 01:08:56 EDT 2007
On Sep 12, 1:05 pm, al... at mac.com (Alex Martelli) wrote:
> Making, say, 'a' hiddenly mean 'x.a', within a function, requires a
> decorator that suitably rewrites the function's bytecode... (after
> which, it WOULD still be terrible and horrible and not to be used, just
> as you say, but it might at least _work_;-). Main problem is, the
> decorator needs to know the set of names to be "faked out" in this
> terrible and horrible way at the time the 'def' statement executes: it
> can't wait until runtime (to dynamically determine what's in var(self))
> before it rewrites the bytecode
All right Alex, and since I had 20 minutes of spare
time I implemented the decorator you are talking about by
using the wonderful byteplay module ;) Here it is:
import dis
from byteplay import Code, LOAD_GLOBAL, LOAD_ATTR, LOAD_FAST,
STORE_FAST
def instance2local(varname):
yield LOAD_FAST, 'self'
yield LOAD_ATTR, varname
yield STORE_FAST, varname
def declare_instance_vars(*varnames):
def dec(f):
c = Code.from_code(f.func_code)
# change LOAD_GLOBAL -> LOAD_FAST
for i, (opcode, value) in enumerate(c.code):
if opcode == LOAD_GLOBAL and value in varnames:
c.code[i] = (LOAD_FAST, value)
# insert instance2local assigments at the beginning
assignments = []
for varname in varnames:
for pair in instance2local(varname):
assignments.append(pair)
c.code[0:0] = assignments
# redefine the code object
f.func_code = c.to_code()
return f
return dec
class Test(object):
def __init__(self):
self.a = 1
self.b = 2
def test1(self):
a = self.a
b = self.b
return a * b
@declare_instance_vars('a', 'b')
def test2(self):
return a * b
co1 = Test.__dict__['test1'].func_code
co2 = Test.__dict__['test2'].func_code
print 'bytecode for test1'
dis.dis(co1)
print 'bytecode for test2'
dis.dis(co2)
t = Test()
assert t.test1() == t.test2()
It is still a hack, since one is not supposed to mess around
with bytecodes, but at least it seems to work ;) [warning:
I have not tested it more than you see]
Michele Simionato
More information about the Python-list
mailing list