Я запускаю этот код:

class timetable(object):
    def __init__(self, date):
        self.date = date
    def outGet(self):
        print("timetable output: ", self.date)

class timetableUpperClass(object):
    def newSubject(self, subjectDate):
        # Define new Class
        execThis = ("day_" + str(subjectDate) + " = timetable(" + str(subjectDate) + ")")
        exec(execThis)

        # Get output
        execThisTwo = ("day_" + str(subjectDate) + ".outGet()")
        print("working command: ", execThisTwo)
        exec(execThisTwo)

p = timetableUpperClass()
p.newSubject(20170829)

Этот код работает как ожидалось. Выход:

working command: day_20170829.outGet()
timetable output:  20170829

Но когда я пытаюсь добавить эту строку в конец python-документа:

day_20170829.outGet()

Я получаю это:

Traceback (most recent call last):
  File "huh.py", line 23, in <module>
    day_20170829.outGet()
NameError: name 'day_20170829' is not defined

Я не понимаю, почему exec () работает правильно, а другой нет.

Я использую Python 3.5.2 в Ubuntu 16.04

1
vexE 29 Авг 2017 в 23:21

3 ответа

Лучший ответ

ОБНОВИТЬ:

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

Взяв свой код и изменив его, чтобы получить то, что я думаю, вы пытаетесь выполнить, у меня есть этот код:

class timetableUpperClass(object):
    def __init__(self):
        self.store_data = {}

    def outGet(self, date):
        return "timetable output: {}".format(date)
        print("timetable output: {}".format(date))

    def newSubject(self, subjectDate):
        self.store_data["day_{}".format(subjectDate)] = self.outGet(str(subjectDate))
        print("working command: ", self.store_data["day_{}".format(subjectDate)])

p = timetableUpperClass()
p.newSubject(20170829)
p.outGet(p.store_data["day_20170829"])

Сообщите мне, что вы думаете об этом коде, или если у вас есть вопросы по использованию слова self.store_data.

Как большинство указывало, вам не нужно и, вероятно, не следует использовать exec.

Однако для точности и для решения проблемы с day_20170829.outGet() вы можете добавить переменные в глобальное пространство имен с exec, используя globals() в качестве второго аргумента для exec.

Итак, для строк:

exec(execThis)

И

exec(execThisTwo)

Измените их на:

exec(execThis, globals())

И

exec(execThisTwo, globals())

Это должно позволить day_20170829.outGet() напечатать результаты, которые вы пытались получить.

Возьмите этот пример. Если мы создаем функцию и используем exec для создания переменной в глобальном пространстве имен, мы можем затем вывести эту строку переменных вне функции:

def create_vars_in_global():
        exec("my_var = 'this is in the global'", globals())

create_vars_in_global()

print(my_var)

Результаты:

this is in the global

Дайте знать, если у вас появятся вопросы.

Вот отредактированная версия вашего кода:

class timetable(object):
    def __init__(self, date):
        self.date = date
    def outGet(self):
        print("timetable output: ", self.date)

class timetableUpperClass(object):
    def newSubject(self, subjectDate):
        # Define new Class
        execThis = ("day_" + str(subjectDate) + " = timetable(" + str(subjectDate) + ")")
        exec(execThis, globals())

        # Get output
        execThisTwo = ("day_" + str(subjectDate) + ".outGet()")
        print("working command: ", execThisTwo)
        exec(execThisTwo, globals())

p = timetableUpperClass()
p.newSubject(20170829)
1
Mike - SMT 29 Авг 2017 в 21:24

Как работает exec ():

Когда вы вызываете exec (), он отделяет любые переменные от основного скрипта. Это означает, что если вы определяете переменную в exec, вам придется распечатать ее и т. Д. В exec ()

Например:

exec("a = 10")    #Defining a
print(a)          #This would give an error
exec("print(a)")  #This would print a

Рекомендуется НЕ использовать exec (), это связано с большими проблемами безопасности, и в общем случае лучше попытаться найти обходной путь, если это возможно

Обходной путь с использованием словарей:

Вместо использования exec () используйте словарь

Я предполагаю, что вы знаете, как это работает, но вот пример:

a = {1:"a", 2:"b", 3:"c"}
print(a[1])
print(a[2])
print(a[3])

Будет ли вывод:

'a'
'b'
'c'
1
Ruler Of The World 29 Авг 2017 в 20:47

exec выполняется в текущем пространстве имен, создавая локальную переменную, но вы не можете напрямую обращаться к этой локальной переменной. Лучше использовать словари:

day = {}
day[subjectDate] = timetable(subjectDate)
day[subjectDate].outGet()
0
juanpa.arrivillaga 29 Авг 2017 в 20:40