在Python中使用指针地址调用函数
我有一个简单的函数,想在两个不同的程序运行中调用它。第一次运行程序时,我把这个函数的指针保存到一个文件里:
import cPickle
def test():
pass
def main():
a = test
pFile = open('test.txt', 'wb')
cPickle.dump(a, pFile)
pFile.close()
第二次我想加载这个文件,然后执行保存在对象里的函数:
import cPickle
def test():
pass
def main():
pFile = open('test.txt', 'rb')
a = cPickle.load(pFile)
pFile.close()
a()
需要注意的是,使用cPickle时,这个方法是有效的,这有点奇怪,因为我原以为这基本上是一个指向函数的指针,而这个指针在运行时会改变?当我打印'a'时,它给我的结果是:function test at 0x0351C170:。
所以我想问的第一个问题是,为什么这能工作,尽管引用地址在运行时应该会改变?
我的第二个问题是,如果它没有改变或者以某种方式不相关,我怎么能仅仅通过字符串:function test at 0x0351C170:来执行这个函数呢?比如说,像这样:
def test():
print 'test'
a = test
a() #outputs: 'test'
b = str(a) #<function test at 0x03509170>
eval(b)() #error
2 个回答
3
你不能在某个特定的地址执行一个函数。
没错,地址在运行时会发生变化。当cPickle加载文件时,它会创建一个新的函数,而你看到的就是这个新函数。这个新函数的地址和原来的函数是不同的。
2
可以查看pickle
的文档:
以下类型是可以被“腌制”的:
- None(空值)、True(真)、和 False(假)
- 整数、长整数、浮点数、复数
- 普通字符串和 Unicode 字符串
- 只包含可“腌制”对象的元组、列表、集合和字典
- 在模块顶层定义的函数
- 在模块顶层定义的内置函数
- 在模块顶层定义的类
- 这些类的实例,其
__dict__
或__setstate__()
是可“腌制”的(具体细节请参见“腌制协议”部分)
所以,pickle
模块实际上是把 Python 的字节码写入到腌制文件中。当这个腌制文件被重新加载时,函数会从代码对象中重新创建。
至于你问题的第二部分,不,单单知道内部地址值是无法直接调用 Python 代码的。