Nie mogę zmusić Pythona do zaimportowania modułu w podfolderze. Pojawia się błąd, gdy próbuję utworzyć wystąpienie klasy z zaimportowanego modułu, ale sam import się udaje. Oto moja struktura katalogów:
Server
-server.py
-Models
--user.py
Oto zawartość 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
I 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)
Błąd to: AttributeError: obiekt „moduł” nie ma atrybutu „Użytkownik”
Odpowiedzi:
Uważam, że musisz utworzyć plik o nazwie
__init__.py
w katalogu Models, aby Python traktował go jako moduł.Następnie możesz:
from Models.user import User
Możesz dołączyć kod do
__init__.py
(na przykład kod inicjujący, którego potrzebuje kilka różnych klas) lub pozostawić to pole puste. Ale musi tam być.źródło
Musisz utworzyć
__init__.py
wModels
podfolderze. Plik może być pusty. Definiuje pakiet.Następnie możesz:
from Models.user import User
Przeczytaj wszystko na ten temat w samouczku Pythona tutaj .
Jest to również dobry artykuł o organizacji plików projektów Pythona tutaj .
źródło
Z powodu braku __init__ wspomnianego powyżej, można by się spodziewać błędu ImportError, który wyjaśniłby problem.
Nie otrzymujesz go, ponieważ „użytkownik” jest również istniejącym modułem w bibliotece standardowej. Twoja instrukcja import przechwytuje tę jedną i próbuje znaleźć w niej klasę User; to nie istnieje i tylko wtedy pojawia się błąd.
Ogólnie dobrym pomysłem jest, aby import był absolutny:
import Server.Models.user
aby uniknąć tego rodzaju dwuznaczności. Rzeczywiście, z Pythona 2.7 „import user” w ogóle nie będzie wyglądał względem bieżącego modułu.
Jeśli naprawdę chcesz importów względnych, możesz je mieć jawnie w Pythonie 2.5 i nowszych, używając nieco brzydkiej składni:
from .user import User
źródło
Prawidłowy sposób zaimportowania modułu znajdującego się w folderze nadrzędnym, gdy nie masz standardowej struktury pakietu, to:
import os, sys CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) sys.path.append(os.path.dirname(CURRENT_DIR))
(możesz połączyć ostatnie dwie linie, ale w ten sposób jest łatwiejszy do zrozumienia).
To rozwiązanie jest wieloplatformowe i jest na tyle ogólne, że nie trzeba go modyfikować w innych okolicznościach.
źródło
Brakuje __init__.py. Z samouczka Pythona:
Umieść pusty plik o nazwie __init__.py w swoim katalogu Models, a wszystko powinno być złote.
źródło
jak wypisujesz parametry
os.path.dirname
.... polecenie?import os, sys CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) sys.path.append(os.path.dirname(CURRENT_DIR))
źródło
Moim preferowanym sposobem jest umieszczenie __init__.py w każdym katalogu zawierającym moduły, które są używane przez inne moduły, aw punkcie wejścia, nadpisanie sys.path, jak poniżej:
def get_path(ss): return os.path.join(os.path.dirname(__file__), ss) sys.path += [ get_path('Server'), get_path('Models') ]
Dzięki temu pliki w określonych katalogach są widoczne do importu i mogę zaimportować użytkownika z Server.py.
źródło
Po przejrzeniu odpowiedzi udzielonych przez tych autorów powyżej - Zorglub29, Tom, Mark, Aaron McMillin, lucasamaral, JoeyZhao, Kjeld Flarup, Procyclinsur, martin.zaenker, tooty44 i debugowaniu problemu, z którym miałem do czynienia, odkryłem inny przypadek użycia z powodu do którego miałem ten problem. Dlatego dodam poniżej moje obserwacje w celach informacyjnych.
W swoim kodzie miałem cykliczny import klas. Na przykład:
src |-- utilities.py (has Utilities class that uses Event class) |-- consume_utilities.py (has Event class that uses Utilities class) |-- tests |-- test_consume_utilities.py (executes test cases that involves Event class)
Pojawił się następujący błąd, gdy próbowałem wykonać python -m pytest tests / test_utilities.py do wykonywania UT napisanych w test_utilities.py.
ImportError while importing test module '/Users/.../src/tests/test_utilities.py'. Hint: make sure your test modules/packages have valid Python names. Traceback: tests/test_utilities.py:1: in <module> from utilities import Utilities ... ... E ImportError: cannot import name 'Utilities'
Sposób, w jaki rozwiązałem ten błąd, polegał na ponownym rozłożeniu kodu w celu przeniesienia funkcjonalności w klasie cyklicznego importu, aby móc usunąć cykliczny import klas.
Zauważ, że mam
__init__.py
plik w moim folderze „ src ”, a także w folderze „ testy ” i nadal byłem w stanie pozbyć się błędu „ ImportError ” po prostu przez ponowne uwzględnienie kodu.Poniższy link stackoverflow zawiera znacznie więcej szczegółów na temat zależności cyklicznych w Pythonie .
źródło