不能调用之前用exec定义的类

时间:2017-08-29 20:21:31

标签: python class

我正在运行此代码:

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()运行正常而另一个没有运行。

我在ubuntu 16.04上运行Python 3.5.2

3 个答案:

答案 0 :(得分:1)

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 :(得分:1)

更新:

使用数据的一种方法是使用字典,最好将所有内容保存在一个类中。

拿你的代码并修改它以获得我认为你正在努力完成的事情我有这个代码:

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()作为{{1}的第二个参数}}

对于行:

exec

exec(execThis)

将其更改为:

exec(execThisTwo)

exec(execThis, globals())

这应该允许exec(execThisTwo, globals()) 打印您尝试获得的结果。

举个例子,如果我们创建一个函数并使用exec在全局名称空间中创建一个变量,那么我们就可以在函数外部打印变量string:

day_20170829.outGet()

结果:

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

答案 2 :(得分:0)

exec在当前命名空间中执行,创建局部变量,但不能直接访问此局部变量。更好地使用词典:

day = {}
day[subjectDate] = timetable(subjectDate)
day[subjectDate].outGet()