cell object dereferencing

P

Peter Otten

Jan said:
Is there a way to dereference a cell object (that is, get
the object that it references to) in Python?

Regards, Jan

I appreciate messages from the future, cryptic as they may be.
So: what cell in what prison?

Sorry, couldn't resist...

Peter
 
J

Jan Decaluwe

Is there a way to dereference a cell object (that is, get
the object that it references to) in Python?

Regards, Jan
 
J

Jan Decaluwe

Peter said:
Jan Decaluwe wrote:




I appreciate messages from the future, cryptic as they may be.
So: what cell in what prison?

Sorry, couldn't resist...

Cell objects are afaik only documented briefly in the Python C API,
so I understand the question may sound cryptic.
For you knowledge, they exist today and are used to implement
nested scopes. The guy able to answer (I hope)
will probably understand the question immediately.

Regards, Jan
 
T

Terry Reedy

Jan Decaluwe said:
Is there a way to dereference a cell object (that is, get
the object that it references to) in Python?

[Background: a cell is an undefined internal implementation object used to
make nested scoping work as advertised. One might think of it as a means
for persisting cross-scope name-binding of objects in intermediate nested
scopes of nested functions. Alternatively, a cell is 'persistent read-only
shadow of an outer local'. For nested functions that access intermediate
locals, .func_closure is a tuple of 'cells'.]

Yes and no, depending on what you mean be 'dereference'. Within the nested
function, you 'dereference' the variable the same way you do any bound
ame -- write it! Outside the function, where the variable has no
conceptual existence, you can grab a cell from the func_closure tuple, but I
know of no way to access its value. Both repr() and str() return a <cell at
xxx: type at yyy> description. If you want a globally accessible value, use
a global variable.

Terry J. Reedy
 
J

Jan Decaluwe

Terry said:
Is there a way to dereference a cell object (that is, get
the object that it references to) in Python?


[Background: a cell is an undefined internal implementation object used to
make nested scoping work as advertised. One might think of it as a means
for persisting cross-scope name-binding of objects in intermediate nested
scopes of nested functions. Alternatively, a cell is 'persistent read-only
shadow of an outer local'. For nested functions that access intermediate
locals, .func_closure is a tuple of 'cells'.]

Yes and no, depending on what you mean be 'dereference'. Within the nested
function, you 'dereference' the variable the same way you do any bound
ame -- write it! Outside the function, where the variable has no
conceptual existence, you can grab a cell from the func_closure tuple, but I
know of no way to access its value.

This is what is mean - so I guess the answer is no.
Both repr() and str() return a <cell at
xxx: type at yyy> description. If you want a globally accessible value, use
a global variable.

The background is that I am writing a small compiler that translates a
(small) subset of Python into another language. I would like to be able to
support free variables as they are likely to be useful in the kind of
code I'm targetting. However, I need to be able to inspect the corresponding
objects for their type etc. Conceptually this should be possible, just as
with globals and locals of functions and frames, but in practice it seems
it isn't - a real pity for which I hope to find a workaround.

Regards, Jan
 
J

Jan Decaluwe

Jan said:
Is there a way to dereference a cell object (that is, get
the object that it references to) in Python?

I got the following response from Samuele Pedroni. I'll repost this
first, and then start thinking about it :)

--

[I was reading the news group through google, feel free to repost this]

well you can write a C extension or use this hack (it's a huge hack but it is safe
and does the trick):

def proto_acc(v=None):
def acc():
return v
return acc
acc0 = proto_acc()
import new
make_acc = lambda cell: (new.function (acc0.func_code,acc0.func_globals,'#cell_acc',acc0.func_defaults,(cell,)))

def cell_deref(cell):
return make_acc(cell)()

# usage

def g(x,y):
def f(): return x,y
return f

f=g(1,2)

f_cells_by_name = dict(zip(f.func_code.co_freevars,f.func_closure))

print cell_deref(f_cells_by_name['x'])
print cell_deref(f_cells_by_name['y'])

regards.
 
T

Terry Reedy

Jan Decaluwe said:
I got the following response from Samuele Pedroni.:
well you can ... use this hack (it's a huge hack but it is safe and does
the trick):
def proto_acc(v=None):
def acc():
return v
return acc
acc0 = proto_acc()
import new
make_acc = lambda cell: (new.function (acc0.func_code,acc0.func_globals,'#cell_acc',acc0.func_defaults,(cell,)))
def cell_deref(cell):
return make_acc(cell)()

Cute, Samuele. If function.func_closure were writable (which it is not)
then I believe the last four lines could be condensed as the more readable

def cell_deref(cell):
acc0.func_closure = (cell,)
return acc0()

but since it is not, you instead make a new function that is a near copy of
acc0 but with (cell,) substituted as *its* func_closure.

Terry J. Reedy
 
J

Jan Decaluwe

Terry said:
the trick):




Cute, Samuele. If function.func_closure were writable (which it is not)
then I believe the last four lines could be condensed as the more readable

def cell_deref(cell):
acc0.func_closure = (cell,)
return acc0()

but since it is not, you instead make a new function that is a near copy of
acc0 but with (cell,) substituted as *its* func_closure.

Aha, *that's* what the last argument is: func_closure. For those interested,
this is not yet in the documentation of module new, but it is documented
in new.function.__doc__.

Thanks a lot for this hack, it looks just what I need. I even start to
understand it, I believe. (Next thing I would like to understand is
how the hell you came up with this!)

Regards, Jan
 
T

Terry Reedy

Jan Decaluwe said:
>(Next thing I would like to understand is how the hell you came up with
this!)

I can't speak for Pedroni, but...
If you start with the two facts I initially stated -- cells are externally
accessible as .func_closure tuple members but their values are only
internally accessible -- and treat them as design guidelines (as Pedroni
did) rather than as deniers of possibility (my mistake), one is pretty much
lead to the conclusion that you need to attach the cells to a function that
reads and returns the value. This is Pedroni's template function. The
third fact -- that .func_closure is read-only, dictates the near-copy via
new instead of simple reuse of the template.

Terry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,475
Latest member
ShannonGro

Latest Threads

Top