473,382 Members | 1,396 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Functions and code objects

Hello all,

I'm trying to extract the code object from a function, and exec it
without explicitly passing parameters.

The code object 'knows' it expects to receive paramaters. It's
'arg_count' attribute is readonly.

How can I set the arg_count to 0, or pass parameters to the code object
when I exec it ?
>>def f(x):
.... print x
....
>>c = f.func_code
type(c)
<type 'code'>
>>exec c
Traceback (most recent call last):
File "<input>", line 1, in ?
TypeError: f() takes exactly 1 argument (0 given)
>>c.co_argcount
1
>>c.co_argcount = 0
Traceback (most recent call last):
File "<input>", line 1, in ?
TypeError: readonly attribute
>>>
Fuzzyman
http://www.voidspace.org.uk/python/index.shtml

Jul 27 '06 #1
6 3108

Fuzzyman wrote:
Hello all,

I'm trying to extract the code object from a function, and exec it
without explicitly passing parameters.

The code object 'knows' it expects to receive paramaters. It's
'arg_count' attribute is readonly.

How can I set the arg_count to 0, or pass parameters to the code object
when I exec it ?
Ok, so now I'm getting somewhere, without really knowing what I'm
doing. Using the CodeType I can create a new code object with identical
attributes, except an 'argcount' of 0.

It doesn't quite work, so I probably need to set some of the attributes
*differently*.

The code I use is :
>>def f(x):
... print x
...
>>c = f.func_code
CodeType = type(c)
a = CodeType(0, c.co_nlocals, c.co_stacksize, c.co_flags, c.co_code,
... c.co_consts, c.co_names, c.co_varnames, c.co_filename,
c.co_name,
... c.co_firstlineno, c.co_lnotab, c.co_freevars, c.co_cellvars)
>>a
<code object f at 01C707A0, file "<input>", line 1>
>>exec a
Traceback (most recent call last):
File "<input>", line 1, in ?
File "<input>", line 2, in f
UnboundLocalError: local variable 'x' referenced before assignment

(the first argument, 0, becomes the 'arg_count' attribute)

So the code object is still creating a local scope, and knows that x is
a local variable. ('co_nlocals' and 'co_varnames' ?).

I'd like to construct the code object so that it takes the parameters
from the enclosing scope (the context I pass into exec I guess),
without clobbering any local variables that may be defined in the code
object.

Anyone got any clues ?
The attributes mean (from http://pyref.infogami.com/type-code ) :

* co_name gives the function name
* co_argcount is the number of positional arguments (including
arguments with default values)
* co_nlocals is the number of local variables used by the function
(including arguments)
* co_varnames is a tuple containing the names of the local
variables (starting with the argument names)
* co_cellvars is a tuple containing the names of local variables
that are referenced by nested functions
* co_freevars is a tuple containing the names of free variables
* co_code is a string representing the sequence of bytecode
instructions
* co_consts is a tuple containing the literals used by the bytecode
* co_names is a tuple containing the names used by the bytecode
* co_filename is the filename from which the code was compiled
* co_firstlineno is the first line number of the function
* co_lnotab is a string encoding the mapping from byte code offsets
to line numbers (for details see the source code of the interpreter)
* co_stacksize is the required stack size (including local
variables)
* co_flags is an integer encoding a number of flags for the
interpreter.

In case anyone wonders, this is purely an experiment in creating
'annoymous code blocks'. :-)

What is a 'free variable' ?

'cell_vars' also looks interesting, but probably better not to mess
with it :-) (I guess it is only relevant for functions defined in the
code block)

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml

Jul 27 '06 #2

Fuzzyman wrote:
Fuzzyman wrote:
Hello all,

I'm trying to extract the code object from a function, and exec it
without explicitly passing parameters.

The code object 'knows' it expects to receive paramaters. It's
'arg_count' attribute is readonly.

How can I set the arg_count to 0, or pass parameters to the code object
when I exec it ?

Ok, so now I'm getting somewhere, without really knowing what I'm
doing. Using the CodeType I can create a new code object with identical
attributes, except an 'argcount' of 0.

It doesn't quite work, so I probably need to set some of the attributes
*differently*.

The code I use is :
>def f(x):
... print x
...
>c = f.func_code
CodeType = type(c)
a = CodeType(0, c.co_nlocals, c.co_stacksize, c.co_flags, c.co_code,
... c.co_consts, c.co_names, c.co_varnames, c.co_filename,
c.co_name,
... c.co_firstlineno, c.co_lnotab, c.co_freevars, c.co_cellvars)
>a
<code object f at 01C707A0, file "<input>", line 1>
>exec a
Traceback (most recent call last):
File "<input>", line 1, in ?
File "<input>", line 2, in f
UnboundLocalError: local variable 'x' referenced before assignment

(the first argument, 0, becomes the 'arg_count' attribute)

So the code object is still creating a local scope, and knows that x is
a local variable. ('co_nlocals' and 'co_varnames' ?).

I'd like to construct the code object so that it takes the parameters
from the enclosing scope (the context I pass into exec I guess),
without clobbering any local variables that may be defined in the code
object.

Anyone got any clues ?
*Damn* I've extracted the code object and told it that it has no
arguments. Executing the code object results in the function object !

The code object is obviously the code object for the function
definition. *sigh*

I was hoping I could get to the code object for the *body* of the
function. Looks like that won't be possible without dis-assembling the
bytecode or other tricks even more hackish than what I've already done.

For the record, the code I was using was :

x = 3
def f(x):
print x

CodeType = type(f.func_code)

def convert_function(f):
code = f.func_code
nlocals = max(code.co_nlocals - code.co_argcount, 0)
newCode = CodeType(0, nlocals, code.co_stacksize, code.co_flags,
code.co_code, code.co_consts, code.co_names,
code.co_varnames, code.co_filename,
code.co_name,
code.co_firstlineno, code.co_lnotab,
code.co_freevars,
code.co_cellvars)
return newCode

print convert_function(f)
exec convert_function(f)

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml

Jul 27 '06 #3
Fuzzyman wrote:
Fuzzyman wrote:
Fuzzyman wrote:
Hello all,
>
I'm trying to extract the code object from a function, and exec it
without explicitly passing parameters.
>
The code object 'knows' it expects to receive paramaters. It's
'arg_count' attribute is readonly.
>
How can I set the arg_count to 0, or pass parameters to the code object
when I exec it ?
>
Ok, so now I'm getting somewhere, without really knowing what I'm
doing. Using the CodeType I can create a new code object with identical
attributes, except an 'argcount' of 0.

It doesn't quite work, so I probably need to set some of the attributes
*differently*.

The code I use is :
>>def f(x):
... print x
...
>>c = f.func_code
>>CodeType = type(c)
>>a = CodeType(0, c.co_nlocals, c.co_stacksize, c.co_flags, c.co_code,
... c.co_consts, c.co_names, c.co_varnames, c.co_filename,
c.co_name,
... c.co_firstlineno, c.co_lnotab, c.co_freevars, c.co_cellvars)
>>a
<code object f at 01C707A0, file "<input>", line 1>
>>exec a
Traceback (most recent call last):
File "<input>", line 1, in ?
File "<input>", line 2, in f
UnboundLocalError: local variable 'x' referenced before assignment

(the first argument, 0, becomes the 'arg_count' attribute)

So the code object is still creating a local scope, and knows that x is
a local variable. ('co_nlocals' and 'co_varnames' ?).

I'd like to construct the code object so that it takes the parameters
from the enclosing scope (the context I pass into exec I guess),
without clobbering any local variables that may be defined in the code
object.

Anyone got any clues ?

*Damn* I've extracted the code object and told it that it has no
arguments. Executing the code object results in the function object !

The code object is obviously the code object for the function
definition. *sigh*

I was hoping I could get to the code object for the *body* of the
function. Looks like that won't be possible without dis-assembling the
bytecode or other tricks even more hackish than what I've already done.

For the record, the code I was using was :

x = 3
def f(x):
print x

CodeType = type(f.func_code)

def convert_function(f):
code = f.func_code
nlocals = max(code.co_nlocals - code.co_argcount, 0)
newCode = CodeType(0, nlocals, code.co_stacksize, code.co_flags,
code.co_code, code.co_consts, code.co_names,
code.co_varnames, code.co_filename,
code.co_name,
code.co_firstlineno, code.co_lnotab,
code.co_freevars,
code.co_cellvars)
return newCode

print convert_function(f)
exec convert_function(f)

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml
Out of curiosity, why are you doing this?

Peace,
~Simon

Jul 27 '06 #4
Fuzzyman wrote:
>I'd like to construct the code object so that it takes the parameters
from the enclosing scope (the context I pass into exec I guess),
without clobbering any local variables that may be defined in the code
object.

Anyone got any clues ?
Does this do what you wanted? Instead of messing about with the code object
just work out which values from the namespace the function actually
expects.
>>def callfromnamespace(fn, namespace):
names = fn.func_code.co_varnames[:fn.func_code.co_argcount]
fn(**dict((name, namespace[name])
for name in names if name in namespace))

>>def f(x, y=99):
z = 2
print x, y, z

>>x = 42
callfromnamespace(f, globals())
42 99 2
>>y = 37
callfromnamespace(f, globals())
42 37 2
>>def testme():
x = 3
callfromnamespace(f, vars())
y = 9
callfromnamespace(f, vars())

>>testme()
3 99 2
3 9 2
Jul 27 '06 #5

Simon Forman wrote:
Fuzzyman wrote:
[snip..]
I was hoping I could get to the code object for the *body* of the
function. Looks like that won't be possible without dis-assembling the
bytecode or other tricks even more hackish than what I've already done.

For the record, the code I was using was :

x = 3
def f(x):
print x

CodeType = type(f.func_code)

def convert_function(f):
code = f.func_code
nlocals = max(code.co_nlocals - code.co_argcount, 0)
newCode = CodeType(0, nlocals, code.co_stacksize, code.co_flags,
code.co_code, code.co_consts, code.co_names,
code.co_varnames, code.co_filename,
code.co_name,
code.co_firstlineno, code.co_lnotab,
code.co_freevars,
code.co_cellvars)
return newCode

print convert_function(f)
exec convert_function(f)

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml

Out of curiosity, why are you doing this?
In Ruby anonymous code blocks (which take parameters and can presumably
return values) are executed within the scope in which they are used,
rather than the scope that they are defined.

I wanted to see how close to that I could get in Python. Obviously code
could be compiled from a string, but I thought extracting it from the
body of a function was closer.

All the best,

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml
Peace,
~Simon
Jul 27 '06 #6

Duncan Booth wrote:
Fuzzyman wrote:
[snip..]
>
Does this do what you wanted? Instead of messing about with the code object
just work out which values from the namespace the function actually
expects.
>def callfromnamespace(fn, namespace):
names = fn.func_code.co_varnames[:fn.func_code.co_argcount]
fn(**dict((name, namespace[name])
for name in names if name in namespace))

>def f(x, y=99):
z = 2
print x, y, z

>x = 42
callfromnamespace(f, globals())
42 99 2
>y = 37
callfromnamespace(f, globals())
42 37 2
>def testme():
x = 3
callfromnamespace(f, vars())
y = 9
callfromnamespace(f, vars())

>testme()
3 99 2
3 9 2
Hmmm... it may do, thanks. :-)

I'll play around, and this may become a blog entry.

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml

Jul 27 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: hokiegal99 | last post by:
A few questions about the following code. How would I "wrap" this in a function, and do I need to? Also, how can I make the code smart enough to realize that when a file has 2 or more bad...
99
by: David MacQuigg | last post by:
I'm not getting any feedback on the most important benefit in my proposed "Ideas for Python 3" thread - the unification of methods and functions. Perhaps it was buried among too many other less...
9
by: peter | last post by:
Hello all, Recently I've started to refactor my code ...(I'm using python 2.3.4) I tried to add extra functionality to old functions non-intrusively. When I used a construct, which involves...
6
by: flamesrock | last post by:
ok, so to my knowledge, object oriented means splitting something into the simplest number of parts and going from there. But the question is- when is it enough? For example I have the following...
27
by: Maximus | last post by:
Hi, I was just wondering, is it good to use return without arguments in a void function as following: void SetMapLayer() { if( !Map ) return; layer = LAYER_MAP; }
19
by: Ross A. Finlayson | last post by:
Hi, I hope you can help me understand the varargs facility. Say I am programming in ISO C including stdarg.h and I declare a function as so: void log_printf(const char* logfilename, const...
11
by: tshad | last post by:
I am setting up some of my functions in a class called MyFunctions. I am not clear as to the best time to set a function as Shared and when not to. For example, I have the following bit...
23
by: Timothy Madden | last post by:
Hello all. I program C++ since a lot of time now and I still don't know this simple thing: what's the problem with local functions so they are not part of C++ ? There surely are many people...
47
by: Albert | last post by:
So structures are useful to group variables, so you can to refer to a collection as a single entity. Wouldn't it be useful to also have the ability to collect variable and functions? Ask K&R...
14
by: Jess | last post by:
Hello, I learned that there are five kinds of static objects, namely 1. global objects 2. object defined in namespace scope 3. object declared static instead classes 4. objects declared...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.