set built-in func_code?
Gerhard Häring
gh at ghaering.de
Tue Sep 9 08:48:35 EDT 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