2017-09-14 30 views
1

나는ImportError를 : 가져 두 파일 사이에 이름을 가져올 수 없습니다 같은

util을이 코드를

mainModule

from src.comp.mypackage.wait import Wait 
from src.comp.mypackage.men import Men, MenItem 

""" Code and stuff using Men and MenItem """ 

if __name__ == '__main__': 
    MenuTestDrive.main() 

남성

from abc import ABCMeta, abstractmethod 
from src.comp.mypackage.util import NullUtil, CompUtil 

from src.comp.mypackage.stack import Stack from src.comp.mypackage.men import Men """ Code and stuff using Men and MenItem """ 

6,및 mainModule을 실행했을 때이 오류가 주어지고있어 : 명령 줄에서 내가 pyCharm을 사용하고

Traceback (most recent call last): 
    File "/home/user/PycharmProjects/pythonProj/pythonDesignPatterns/src/comp/mypackage/mainModule.py", line 2, in <module> 
    from pythonDesignPatterns.src.comp.mypackage.men import Men, MenItem 
    File "/home/user/PycharmProjects/pythonProj/pythonDesignPatterns/src/comp/mypackage/men.py", line 2, in <module> 
    from pythonDesignPatterns.src.comp.mypackage.iterator import NullUtil, CompUtil 
    File "/home/user/PycharmProjects/pythonProj/pythonDesignPatterns/src/comp/mypackage/util.py", line 2, in <module> 
    from pythonDesignPatterns.src.comp.mypackage.men import Men 

ImportError: cannot import name 'Men' 

하지만 오류가 동일합니다.

필자는 더 많은 코드를 제공 할 수 있지만 클래스 사용에 대해서는 아무런 생각이 없으며 혼란 스러울뿐입니다.

어디에서 실패를 찾아야합니까?

+0

'남성'이라는 이름이 '남성용'패키지에 실제로 있습니까? 귀하의 질문에 그 정의를 제공해 주시겠습니까? – Grigoriy

답변

2

TL; DR : 당신이 모듈 men에서 모듈 util 수입하는 경우 모듈 util에서 가져 오기 모듈 men을 가질 수 있도록 파이썬, 원형의 수입을 허용하지 않습니다.

긴 대답 : 당신은 파이썬 import, class, def 등 실제로 실행 문 및 모든 (또는 거의) 런타임에 발생이라는 것을 이해해야한다

. 주어진 프로세스에서 모듈을 처음으로 가져 오면 모든 최상위 명령문이 순차적으로 실행되고 인스턴스 객체가 속성으로 모든 최상위 이름을 사용하여 생성됩니다 (class, defimport 모든 바인드 이름) sys.modules 캐시 dict에 삽입되므로 동일한 모듈을 다음에 가져 오면 캐시에서 직접 가져옵니다. 처음 가져올 때 사용자의 경우

은의 men 모듈은 파이썬 런타임이 util.py (또는 .pyc 파일) 파일의 위치를 ​​생성하고 실행한다, 그래서 아직 sys.modules에없는 util 모듈을 수입하려고합니다. 그런 다음 from src.comp.mypackage.men import Men에 도달합니다. 이 시점에서 men.py은 아직 완전히 실행되지 않았기 때문에 Men 특성이 없습니다.

표준 솔루션은 순환 종속성을 세 번째 모듈로 추출하거나 두 가지 모듈을 하나의 단일 모듈로 병합하는 것입니다. 이는 구체적인 케이스에 맞는 것이 무엇인지에 달려 있습니다 (항상 낮은 결합의 모듈을 갖는 것이 목표 임). 높은 응집도). FWIW, 순환 의존성은 언어가 무엇이든 상관없이 나쁜 디자인으로 간주됩니다.

때로는 (코드 및 특정 가져 오기 순서에 특정 구조를 적용하는 복잡한 프레임 워크에서) 순환 의존성 체인으로 끝날 수 있습니다 (예 : A.funcX는 By, B 마지막으로 A.funcZ에 의존하는 E에 의존하는 D에 의존하는 C에 달려있다.) 그리고/또는 깔끔하게 리팩토링하기가 매우 어렵다.최후의 수단으로 함수 내에서 import 문을 연기 할 가능성이 있습니다 (위의 경우는 A.funcX입니다). 이것은 이고 여전히으로 간주되며 실제로는 최후의 수단으로 만 사용해야합니다.

패키지 이름 지정 체계의 강한 Java 영향을 줄 수 있습니다. 파이썬은 자바가 아닙니다! 자바에는 아무런 문제가 없습니다. 단지 these are two wildly different languages이고, wildly different designs, idioms and philosopies입니다.

파이썬에서 Java 관용구와 습관을 강요하려는 것은 고통과 좌절감을 경험하게 될 것입니다. (여기까지 했으니 까 ...), 여기 내 조언은 다음과 같습니다. 대신에 파이썬을 배우기 시작하십시오. 구문은 실제로는 언어의 일부일 뿐이며 반드시 중요한 것은 아닙니다. 파이썬에서는 중첩 된 배열을 선호하고 클래스 당 하나의 모듈을 갖기 위해 노력하지 않고 하나의 단일 모듈로 전체 (마이크로) 프레임 워크를 가질 수 있습니다. 서브 모듈로 분할 할 실질적인 이유가 없다면 괜찮습니다.

+0

이것은 자바에서 번역 된 디자인 패턴 소스 코드 였지만 일반적으로 모델 유사 오브젝트를 그룹화하고 아무 것도 apport하지 않을 때 객체를 병합합니다 (예 : Java 인터페이스). 그러나 이러한 패턴의 경우 Java 디자인 중 일부가 있습니다. . 어쨌든 조언 주셔서 감사합니다. 좋은 것입니다. – madtyn