2016-02-25 2 views
0

можно определить как классы и функцию в exec'd коды без проблем:Определение функций и классов в exec в Python 2.7?

my_func = """ 
    def test_func(): 
     print "Hi from test_func!" 
    """ 
my_class = """ 
    class test_class: 
     def __init__(self): 
      self.a = "a" 
    """ 

def call_func(): 
    exec(my_func) 
    test_func() 

def call_class(): 
    exec(my_class) 
    a = test_class() 

>>> call_func() 
Hi from test_func! 

>>> call_class() 
a 

Однако определить как класс и функцию, которая использует этот класс в exec'd результатов коды в NameError, потому что класс не заканчивается в правильном объеме:

my_class_fun = """ 
class test_class_2: 
    def __init__(self): 
     self.a = "a" 

def test_func_2(): 
    a = test_class_2() 
    print(a.a) 
""" 

def test_2(): 
    exec(my_class_fun) 
    test_func_2() 

>>> test_2() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 3, in test_2 
    File "<string>", line 7, in test_func_2 
NameError: global name 'test_class_2' is not defined 

Передача globals() в качестве второго аргумента exec так, что все заканчивается в глобальном пространстве имен исправлений этой проблемы.

Вопрос, почему это необходимо? test_class_2 и test_func_2 похоже, что оба они должны быть локальными для test_2, так почему не test_func_2 есть доступ к test_class_2?

EDIT:

По сути, мой вопрос почему test_2() выше отличается от чего-то вроде этого кода, который работает отлично:

def test_func(): 
    class test_class: 
    def __init__(self): 
     self.a = "a" 
    def test_func_inner(): 
    c = test_class() 
    print(c.a) 
    test_func_inner() 

>>> test_func() 
a 
+0

вопрос, который я помечена как дубликат использует S слегка отличающийся код, но я думаю, что ответ также отвечает на ваш вопрос. Пожалуйста, уточните свой вопрос, если вы считаете, что что-то остается без ответа. – BrenBarn

+0

Этот вопрос использует Python 3, тогда как я использую 2.7. Я знаю, что функция exec работает по-разному в 3 (т. Е. Это фактическая функция, тогда как в 2 это утверждение), но я не знаю, изменит ли это ответ. Вполне возможно, что основной механизм, с которым они оба становятся, одинаковый. – seaotternerd

+1

Ключевым моментом является то, что когда глобальные переменные и местные жители отличаются друг от друга, «код выполняется, как если бы он был встроен в определение класса», и это [https://docs.python.org/3/library/functions.html #exec] (без изменений) в Python 3. – BrenBarn

ответ

0

Поскольку ваш класс (и функции) не в глобальном пространстве

Demo:

>>> def test_2(): 
...  exec(my_class_fun) 
...  global test_class_2 
...  global test_func_2 
...  test_func_2() 
... 
>>> test_2() 
a 
+0

Правильно, но мой вопрос, почему они должны быть? Почему не так хорошо, чтобы они оба были локальными для test_2? – seaotternerd

+0

@seaotternerd, потому что вы запускаете exec в локальном пространстве test_2 и test_func_2, не знаете, где получить test_class_2, когда мы помещаем test_class_2 в глобальное пространство, тогда функция test_func_2 знает, где получить test_class_2 –

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