2016-02-25 26 views
0

您可以定義exec'd代碼的類和功能沒有問題:在Python 2.7中定義exec中的函數和類?

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_2test_func_2看起來應該都是本地的test_2,那麼爲什麼不test_func_2有權訪問test_class_2

編輯:

從根本上說,我的問題是,爲什麼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

因爲你的類(和功能)未在全球空間

演示:

>>> 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因爲你在test_2的本地空間運行exec,而test_func_2不知道在哪裏得到test_class_2,當我們把test_class_2放到全局空間中時,然後函數test_func_2知道從哪裏得到test_class_2 –