2016-01-13 82 views
1

假設您創建了一個名爲app的Python程序包,它包含一個名爲foo的模塊,該模塊具有一個名爲say_hello的功能,該功能將Hello!打印到控制檯。何時需要修改Python __init__文件?

假設您還創建了第二個名爲boss_app的Python程序包,該程序包有一個模塊mainappboss_app位於相同的目錄中,並且該目錄位於Python路徑中。此外,__init__文件全部爲空。其結構是:

app 
    __init__.py 
    foo.py 
boss_app 
    __init__.py 
    main.py 

我想導入到app這樣boss_app.main我可以調用app.foo.say_hello

我使用這個命令:

import app 

app.foo.say_hello() 

,我希望在控制檯中看到:

>>>> Hello! 

相反,我得到的行爲是app進口它沒有訪問foo

我想出瞭解決的辦法是修改app.__init__,使其包含以下命令:

from .foo import * 

現在,我得到預期的行爲。

是否總是需要創建一個自定義__init__的包,如果該包將被從外面包進口?

+0

如果你想具體'進口app.foo'纔可以使用'app.foo.say_hello()',那麼它完全沒有離開'__init __。py'空。因此,您真的可以選擇與您想要的命名空間相比多少便利。 – Evert

+0

但是,如果我想'導入應用程序'並有權訪問它的名稱空間,那麼我必須修改'__init__'的權利? –

+1

推薦閱讀:https://docs.python.org/3/tutorial/modules.html – jonrsharpe

回答

1

import app 

只運行app/__init__.py並使其初始化提供用作app.SOMENAME一切。如果你想app.foo模塊可用,你需要說import app.foo。這將加載模塊。這種區別的一個常見例子可能是import os vs import os.path。正因爲你說import os,你將不會有os.path包的內容可用。

你不必打破模塊到包,但它有助於避免模塊名稱衝突。它也可能有助於使這些模塊的用戶清楚地理解概念。

+0

這似乎可以成爲我的問題的答案。但是,在你的例子中,如果我導入'import os',我仍然可以做一些類似'os.path.exists(file_name)'的操作。我沒有看過關聯的'__init__'文件。它可以很好地包含適當的進口聲明。你怎麼看? –

+1

是的,這意味着'os'模塊內有一個'path'類(並且存在)。 –

+0

所以你說的是,一個空白的'__init__'將允許類沒有額外的努力被識別,但沒有與類沒有關聯的功能? –