I have a simple function I want to call in two separate program executions. The first time I run the program it saves the function pointer into a file:
import cPickle
def test():
pass
def main():
a = test
pFile = open('test.txt', 'wb')
cPickle.dump(a, pFile)
pFile.close()
The second time I want to load the file and execute the function saved in the object:
import cPickle
def test():
pass
def main():
pFile = open('test.txt', 'rb')
a = cPickle.load(pFile)
pFile.close()
a()
Note that with cPickle, this works, which is a bit odd, since I figured this is basically a pointer to the function and that this would change at runtime? When I print 'a', it gives me something like :function test at 0x0351C170:.
So I guess my first question is, why does this work, even though the reference address should change at runtime?
And my second question would be, if it does not change/or it's irrelevant somehow, how can I execute the function just from having the string: :function test at 0x0351C170:. e.g. something like:
def test():
print 'test'
a = test
a() #outputs: 'test'
b = str(a) #<function test at 0x03509170>
eval(b)() #error
2 Answers 2
You cannot execute a function at a given address.
Yes, reference address changes at run time. When cPickle loads the file, it creates a function and what you see is that function. It will not have the same address as the original function.
1 Comment
See the pickle documentation:
The following types can be pickled:
- None, True, and False
- integers, long integers, floating point numbers, complex numbers
- normal and Unicode strings
- tuples, lists, sets, and dictionaries containing only picklable objects
- functions defined at the top level of a module
- built-in functions defined at the top level of a module
- classes that are defined at the top level of a module
- instances of such classes whose
__dict__or__setstate__()is picklable (see section The pickle protocol for details)
So the pickle module actually writes out the Python bytecode in the pickle file. When the pickle file is reloaded, the function is recreated from the code object.
To answer the second part of your question, no, it is not possible to directly call Python code just by knowing the internal address value.