2011-12-28 6 views
2

У меня есть простая функция, которую я хочу вызвать двумя отдельными программами. Первый раз, когда я запустить программу она сохраняет указатель на функцию в файл:Вызов функции в 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 на 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

Смотрите pickle documentation:

Следующие типы могут быть солеными:

  • None, True, и ложные
  • целые, длинные целые числа, числа с плавающей точкой , комплексные номера
  • нормальные и Unicode строки
  • кортежей, списки, множество и словари, содержащие только пригодны для консервирования объектов
  • функции определены на верхнем уровне модуля
  • встроенных функций, определенных на верхнем уровне модуля
  • классов, которые определены на верхнем уровне модуля
  • экземпляров таких классов, чьи __dict__ или __setstate__() это пригодны для консервирования (смотрите раздел протокол рассола для деталей)

Таким образом, модуль pickle фактически выписывает байт-код Python в файле pickle. Когда файл pickle перезагружается, функция воссоздается из объекта кода.

Чтобы ответить на вторую часть вашего вопроса, нет, невозможно напрямую вызвать код Python, просто зная значение внутреннего адреса.

+0

спасибо! это хорошо объяснено. – Muppet

2

Вы не можете выполнить функцию по заданному адресу.

Да, адрес ссылки меняется во время выполнения. Когда cPickle загружает файл, он создает функцию, и то, что вы видите, является этой функцией. Он не будет иметь тот же адрес, что и исходная функция.

+0

Хм, это позор. Спасибо хоть! – Muppet

Смежные вопросы