set built-in func_code?

Gerhard Häring gh at ghaering.de
Tue Sep 9 14:48:35 CEST 2003


Birgit Rahm wrote:
> Hallo,
> I have a program (not written by me :-( ) that loads socalled helpfunctions
> and executes that dynamically.
> One error message was : ... cant get the func_code of the helpfunctionX.

That sounds strange. But the reason is most probably that helpfunctionX 
is in fact not a function.

> Which reason this message has, I dont now.
> My main problem is, that I dont know what func_code is : a built-in function
> or attribute or what ? And why is it used.

I don't know why it's used either, because I don't know the program you 
use :) I think you're relatively new to Python (only saw you posting 
here recently) :-) So what we're touching here is advanced stuff, but 
I'll try to explain it as good as I can:

*Everything* in Python is an object, including functions. Here's an 
excerpt from an interactive session:

 >>> def times2(x): return 2*x
...
 >>> times2
<function times2 at 0x007E68F0>
 >>> type(times2)
<type 'function'>
 >>>

So, times2 is a function object. Being an object, it also has attributes:

 >>> dir(times2)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', 
'__get__', '__getattribute__', '__hash__', '__init__', '__module__', 
'__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__str__', 'func_closure',  'func_code', 'func_defaults', 
'func_dict', 'func_doc', 'func_globals', 'func_name']

Now it's relatively clear what func_name might be:

 >>> times2.func_name
'times2'

But there's also more advanced stuff like the func_code attribute. 
func_code is a code object (yes, *again* an object), that contains the 
Python bytecode for the function in question. If you really wanted to, 
you could replace the code object of the function with a new code 
object, that does something totally different. This is probably one of 
the deepest hacks you can do in Python :-D

So if, for example, I wanted times2 to return "x*3" instead of "x*2", I 
could use something like:

def changeMeaningOfTimes2():
     def __tmpfunc(x):
         return x*3

     times2.func_code = __tmpfunc.func_code

As I already said, this is a very ugly hack, that is seldom, if ever 
justified.

If you're just trying to make a call to times2() invoke something 
different, you could just do:

def __tmpfunc(x): return 3*x
times2 = __tmpfunc()

because all this does is bind the name 'times2' to a different function 
object.

I hope this gives you an insight in the possibilites of what you *can* 
do with Python. And that not everything you *can* do is necessarily a 
good idea ;-)

That being said, what you described sounds to me like the real problem 
is that a name helpfunctionX is assigned to something other than a 
function and that your program tries to get the func_code attribute from 
this object, which fails, because it's not a function but something else.

ciao,

-- Gerhard





More information about the Python-list mailing list