2015-08-10 2 views
1

У меня есть текстовый файл, который содержит функцию Python, как это:Чтение функции питона из текстового файла и присвоить его переменной

a.txt

def func(): 
    var = 5 
    return var 

А потом я прочитал этот файл скрипт Python:

b.py

python_file = open("a.txt").read() 

Теперь я хочу назначить функцию файла a.txt переменной, не беспокоясь о имени функции и ее выполняя. Я пытался что-то вроде этого:

python_file = open("a.txt").read() 
b = exec(python_file) 
b() 

Но это не сработало, я попробовал execfile, а также.

+1

Почему бы вам просто не переименовать его в '.py' и' import' это обычным способом? В любом случае, обратите внимание, что 'exec' ничего не возвращает, прочитайте его [документацию] (https://docs.python.org/3/library/functions.html#exec). – jonrsharpe

+0

@jonrsharpe Сэр Это .txt файл. поэтому не может импортировать.и требование такое, что я не знаю имени функции txt-файла в файле python. –

+0

... Python file * is * также просто текстовый файл, почему бы не 'os.rename' его? – jonrsharpe

ответ

2

После того как вы exec соновской строку, вы можете позвонить func напрямую, так как он был добавлен в текущее пространство имен:

>>> exec("""def func(): 
    var = 5 # note that the semicolons are redundant and unpythonic 
    return var""") 
>>> func() 
5 

Per its documentationexec фактически не вернуть ничего, так что нет никакого смысла присвоение, например, foo = exec(...).


Чтобы увидеть, что имена локально определены в коде выполняется, передать пустой словарь для exec как locals параметра:

>>> ns = {} 
>>> exec("""def func(): 
    var = 5 
    return var""", globals(), ns) 
>>> ns 
{'func': <function func at 0x0315F540>} 

Вы можете назначить функцию и называть его, как вы обычно будет:

>>> b, = ns.values() # this will only work if only one name was defined 
>>> b() 
5 
+0

Я не хочу называть его именем функции. Я не знаю имя функции в файле python. Я хочу назначить переменной, какая бы функция там –

+0

@AshishNautiyal хорошо, что, вероятно, будет жестким. Что вы на самом деле пытаетесь достичь? – jonrsharpe

+0

согласился сэр. Но я хочу найти способ присвоить ему переменную. –

2

Прежде чем предложить свое решение, я настоятельно предостерегаю от этого, если вы не знаете наверняка, нет вредоносного кода в a.txt.

Мое решение использует функцию execfile, чтобы загрузить текстовый файл и возвращает первый объект (может быть переменная или функция):

def load_function(filename): 
    """ Assume that filename contains only 1 function """ 
    global_var = dict() 
    execfile(filename, global_var) 
    del global_var['__builtins__'] 
    return next(global_var.itervalues()) 

# Use it 
myfunction = load_function('a.txt') 
print myfunction() 

Update

Чтобы быть немного более осторожным, модифицировать return, как показано ниже, так что она пропускает переменные (однако она не может пропустить объявление класса).

return next(f for f in global_var.itervalues() if callable(f)) 

Update 2

Спасибо johnsharpe за указание на то, что не существует в Python 3. нет execfile Вот модифицированный раствор, который используют вместо exec. На этот раз функция должна быть найдена в «локальной» области.

def load_function(filename): 
    """ Assume that filename contains only 1 function """ 
    with open(filename) as f: 
     file_contents = f.read() 
     global_var = dict() 
     local_var = dict() 
     exec file_contents in global_var, local_var 
     return next(f for f in local_var.itervalues() if callable(f)) 

# Use it 
myfunction = load_function('a.txt') 
print myfunction() 
+0

Обратите внимание, что Python 3 не имеет 'execfile', см., Например, https://docs.python.org/3/whatsnew/3.0.html#builtins, http://stackoverflow.com/q/436198/3001761 – jonrsharpe

+0

Мой плохой. У меня нет Python 3. В этом случае ваше решение (открытый текстовый файл, чтение содержимого, call exec) будет объединено с моим (получить первый вызов из глобального пространства имен). –

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