2009-01-19 92 views
64

我似乎無法讓Python將子模塊導入到子文件夾中。當我嘗試從導入的模塊創建類的實例時,出現錯誤,但導入本身成功。這裏是我的目錄結構:無法從不同的文件夾導入Python

Server 
    -server.py 
    -Models 
     --user.py 

這裏的server.py的內容:

from sys import path 
from os import getcwd 
path.append(getcwd() + "\\models") #Yes, i'm on windows 
print path 
import user 

u=user.User() #error on this line 

而且user.py:

class User(Entity): 
    using_options(tablename='users') 

    username = Field(String(15)) 
    password = Field(String(64)) 
    email = Field(String(50)) 
    status = Field(Integer) 
    created = Field(DateTime) 

的錯誤是: AttributeError的: '模塊'對象沒有屬性'用戶'

+1

你能粘貼錯誤信息嗎? – 2009-01-19 03:55:38

回答

96

我相信你需要創建一個名爲的文件放在Models目錄下,以便python將其視爲一個模塊。

然後,你可以這樣做:

from Models.user import User 

可以包括在__init__.py(即幾個不同的類需要實例的初始化代碼)代碼或留空。但它一定在那裏。

+1

謝謝,我之前從未聽說過包裝。 – ryeguy 2009-01-19 04:03:38

+0

實際上,當導入Python對待blah.py和blah/__ init__.py完全一樣。 – 2009-01-19 13:54:36

+1

這是不明顯的......我對自己說:RTFM FMF – 2015-03-12 08:22:36

20

您必須在Models子文件夾中創建__init__.py。該文件可能爲空。它定義了一個包。

然後,你可以這樣做:

from Models.user import User 

閱讀所有關於它在python教程,here

還有一篇關於python項目文件組織的文章here

7

您缺少__init__.py。從Python教程:

The __init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, __init__.py can just be an empty file, but it can also execute initialization code for the package or set the __all__ variable, described later.

把你的模型目錄下名爲__init__.py的空文件,所有的應該是金色的。

10

import user

u=user.User() #error on this line

由於缺少上述的__init__,你會期望一個導致問題更清晰的ImportError。

您不會得到一個,因爲'用戶'也是標準庫中的現有模塊。您的導入語句會捕獲該語句並嘗試在其中找到User類;那不存在,只有這樣你纔會得到錯誤。

它通常是一個好主意,使你的進口絕對:

import Server.Models.user 

避免這種含糊不清的。事實上,從Python 2.7'導入用戶'根本不會相對於當前模塊。

如果您確實需要相對導入,您可以在Python 2中顯式地使用它們。5只及以上使用有點醜陋的語法:

from .user import User 
6

導入位於父文件夾的模塊的正確方法,當你沒有一個標準的封裝結構是:

import os, sys 
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) 
sys.path.append(os.path.dirname(CURRENT_DIR)) 

(你可以合併最後兩行,但這種方式更容易理解)。

該解決方案是跨平臺的,通用性足以在其他情況下無需修改。

0

glarrain的解決方案效果最好。我遇到了Python無法識別我的Python模塊的問題,並給了我'找不到模塊'的錯誤。對我來說,即使在添加__init__.py文件並正確導入模塊之後,我仍然得到相同的錯誤。 我按照glarrain的回答解決了問題。

1

你如何寫出參數os.path.dirname ....命令?

import os, sys 
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) 
sys.path.append(os.path.dirname(CURRENT_DIR)) 
0

我的首選方法是對包含習慣其他模塊模塊每個目錄__init__.py,並在入口點,覆蓋下面的sys.path:

def get_path(ss): 
    return os.path.join(os.path.dirname(__file__), ss) 
sys.path += [ 
    get_path('Server'), 
    get_path('Models') 
] 

這使指定目錄中的文件可以導入,並且可以從Server.py導入用戶。