2009-01-19 12 views
64

Python'u bir alt klasörde bir modül almak için kullanamıyorum. İçe aktarılan modülden sınıfın bir örneğini oluşturmaya çalıştığımda hata alıyorum, ancak içe aktarmanın kendisi başarılı. hatadırPython'u farklı bir klasörden içe aktarma açılamıyor

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) 

:

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 

Ve user.py: AttributeError:

İşte
Server 
    -server.py 
    -Models 
     --user.py 

server.py içeriği var: 'modülü' İşte benim dizin yapısı nesne hiçbir özellik 'Kullanıcı'

+1

Hata mesajını yapıştırabilir misiniz? –

cevap

96

sanaadlı bir dosya oluşturmak için gereken inanmak vardır Modeller dizininde, böylece python bunu bir modül olarak ele alır.

Sonra yapabilirsiniz:

from Models.user import User 

Sen __init__.py (birkaç farklı sınıfları ihtiyaç örneğin başlatma kodu) kodu dahil veya boş bırakabilirsiniz. Ama orada olmalı.

+1

Teşekkürler, daha önce hiç bu paketten haber almadım. – ryeguy

+0

Aslında, Python'u içe aktarırken blah.py ve blah/__ init__.py tam olarak aynı davranır. –

+1

Bu açık değildi ... Kendime şunu söylüyorum: RTFM FMF –

20

Sen Models alt klasör üzerinde __init__.py oluşturmak zorunda. Dosya boş olabilir. Bir paketi tanımlar.

Sonra yapabilirsiniz:
from Models.user import User 

piton öğretici, here onunla ilgili her şeyi okuyun.

da piton projelerinin here dosya organizasyonu hakkında iyi makale vardır.

+0

Dosya boş DEĞİLDİR? – darkgaze

7

Eksiksiniz __init__.py. Python öğretici Gönderen:

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.

sizin Modeller dizinde __init__.py adında boş bir dosya koyun ve tüm altın olmalıdır.

10

import user

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

__init__ eksikliği yukarıda belirtilen Çünkü, sorunun daha net kılacak bir ImportError beklenebilir.

Bir tane almazsınız çünkü 'kullanıcı' ayrıca standart kitaplıktaki varolan bir modüldür. İçe aktarma ifadeniz onu alır ve Kullanıcı sınıfını bulmaya çalışır. Bu yok ve sadece o zaman hata alırsınız.

Bu sizin ithalat mutlak yapmak için iyi bir fikir genellikle:

import Server.Models.user 

belirsizlik bu tür önlemek için. Aslında Python 2.7 'ithalat kullanıcısı', mevcut modüle göre hiç görünmeyecek.

Göreceli ithalatı gerçekten istiyorsanız, bunları Python 2'de açıkça kullanabilirsiniz.biraz çirkin sözdizimi kullanılarak 5 ve yukarı:

from .user import User 
6

bir üst klasörü bulunan bir modülü almak için doğru yol, standart paket yapısına sahip olmayan, geçerli:

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

(Son iki çizgiyi birleştirebilirsiniz, ancak bu şekilde anlamak daha kolaydır.

Bu çözüm çapraz platformdur ve diğer durumlarda değişiklik yapmaya gerek duymayacak kadar geneldir.

0

Glarrain tarafından çözüm en iyi şekilde çalışır. Python modülümü tanıyamadım ve 'modül bulunamadı' hatasını verdim. Benim için __init__.py dosyalarını ekledikten ve modülleri uygun şekilde içe aktardıktan sonra bile hala aynı hatayı aldım. Glarrain'in yanıtını takip ederek sorunu çözdüm.

+0

Bu, cevabına en iyi şekilde bir yorum yapmış olabilir. – Ben

1

os.path.dirname .... komutunu nasıl yazıyorsunuz?

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

Tercih ettiğim yolu diğer modüllerle alışması modülleri içeren her dizinde __init__.py sahip olmaktır ve giriş noktasında, sys.path aşağıda geçersiz:

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

Bu belirtilen dizinlerdeki dosyaları içe aktarma için görünür yapar ve Server.py'den kullanıcı alabilir.