2017-07-31 86 views
0

我有一個超類的自初始化實例有條件進口,但子類不能看到該模塊(Python的2.7):子類__init__沒有看到超conditonally導入模塊

class A(object): 
    def __init__(self, arg1): 
     self.attr1 = self.method1(arg1) 

    def method1(self, arg1): 
     if arg1 == 'foo': 
      import amodule 
      return amodule.method1() 
     else: 
      return 'not a dependency on foo' 


class B(A): 
    def __init__(self, arg1): 
     super(B, self).__init__(arg1) 
     if arg1 == 'foo': 
      self.attr2 = self.method2(self.attr1) 

    def method2(self, attr1): 
     return amodule.method2() 

if __name__=='__main__': 
    b = B("foo") 
    print b.attr2 

這將引發NameError: global name 'amodule' is not defineda = A("foo")工程就好了

在這種情況下,super調用是否應該執行import amodule? (並且使用import應該將模塊置於全局模式?)

+1

'amodule'是*局部變量*。你爲什麼會認爲你可以在'method2'中訪問它?另外,'import'語句不會在全局名稱空間中綁定模塊名稱,而是在任何名稱空間中綁定import語句。再次,這將是* local1到'method1' *。 –

+0

不會將當前正在執行的模塊的全局名稱空間導入add/amodule /? (\_\_主要\_\_)? – cowbert

+1

不,它不會自己檢查這個'def f():import sys',然後調用'f()'看看sys是否在全局命名空間中,它不是(除非它已經)。 –

回答

2

是否不將add/amodule /導入到當前執行模塊 的全局名稱空間? (__main__)?

沒有,模塊添加到sys.modules但如果是在本地進口的,那麼你將不會有任何引用了。即名稱amodule現在不見了。

,您仍然可以訪問使用sys.modules模塊:

def method2(self, attr1): 
    import sys 
    return sys.modules['amodule'].method2() 

或者你可以再次使用import amodule導入它,它會從sys.modules有所回升。


# Here b.py contains 
# print('Module b was imported') 

def func1(): 
    print('inside func1') 
    import b 

def func2(): 
    print('inside func2') 
    import sys 
    print(sys.modules['b']) 
    import b 


def func3(): 
    print('inside func3') 
    import b 
    import sys 
    print('Deleted b') 
    del sys.modules['b'] 
    import b 


func1() 
print() 
func2() 
print() 
func3() 

演示:

inside func1 
Module b was imported 

inside func2 
<module 'b' from '/Users/ashwini/py/b.py'> 

inside func3 
Deleted b 
Module b was imported 
+0

我也可以將它作爲一個實例對象。不幸的是,導入這個模塊有點貴。 – cowbert

+1

@cowbert這些計算只會在第一次導入時發生,之後的導入將會選擇已導入的模塊,除非您從'sys.modules'中刪除它。檢查答案中的示例。 –

0

嘗試將import amodule放在程序的第一行。

原因是amodule是在method1中導入的,method2沒有訪問權限。

+0

導入是有條件的,因爲沒有提到的具體原因(因爲它與手頭的問題無關)。 – cowbert

0

如果你按照你的代碼,你會看到你沒有達到method1()。

當你創建對象 b = B(foo) 你去通過A. 初始化()監守呼籲超()。但是,您的init類A()不包含任何導入語句。然後A.__init__部分完成,並且您繼續B.__init__()。下一個命令是對amodule對象的調用,它根本沒有被導入。

您可以添加一個輔助方法,它檢查arg是否等於'Foo',如果是,則導入模塊。然後在A.__init__()函數中添加對此函數的調用。

另一個說明,__init__()工作是初始化變量。它不應該返回任何東西。

+0

A. \ _ \ _ init \ _ \ _()調用A.method1()... – cowbert

+0

你在哪裏看到\ _ \ _ init _ _ _ _()返回任何東西?它會初始化變量,它們的初始值應該是內部方法的返回值... – cowbert

相關問題