можно определить как классы и функцию в 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
вопрос, который я помечена как дубликат использует S слегка отличающийся код, но я думаю, что ответ также отвечает на ваш вопрос. Пожалуйста, уточните свой вопрос, если вы считаете, что что-то остается без ответа. – BrenBarn
Этот вопрос использует Python 3, тогда как я использую 2.7. Я знаю, что функция exec работает по-разному в 3 (т. Е. Это фактическая функция, тогда как в 2 это утверждение), но я не знаю, изменит ли это ответ. Вполне возможно, что основной механизм, с которым они оба становятся, одинаковый. – seaotternerd
Ключевым моментом является то, что когда глобальные переменные и местные жители отличаются друг от друга, «код выполняется, как если бы он был встроен в определение класса», и это [https://docs.python.org/3/library/functions.html #exec] (без изменений) в Python 3. – BrenBarn