2016-08-28 1 views
0

죄송합니다. 이미 용어를 사용하여 답변을 얻었다면 검색 할 필요가 없습니다.Python - 패키지 모듈을 독립 실행 형으로 사용하는 경우 패키지를 가져 오는 경우?

나는 하나 개의 프로젝트를 가지고 : class2class1에서 몇 가지를 수입하고 있지만, 각 내가 실행 자주 각각의 클래스를 사용하여 자신의 if __name__ == '__main__'을 가지고

project1/ 
    class1.py 
    class2.py 

. 그런 다음 두 번째 프로젝트에서 각 클래스의 하위 클래스를 만듭니다 (project1). 그래서 나는 내가 잘 project2로 가져올 수 있도록 패키지로 project1 싶습니다 :

project2/ 
    project1/ 
     __init__.py 
     class1.py 
     class2.py 
    subclass1.py 
    subclass2.py 

을하지만, 나는이 함께 오기에 문제가 있어요. 내가 project1 패키지를 만든 경우 class2.pyclass1.py 코드를 from project1.class1 import class1으로 가져오고 싶습니다. 이로 인해 project2 코드가 올바르게 실행됩니다. 하지만 이제 project1을 패키지로 사용하지 않고 해당 디렉토리에서 코드를 직접 실행하면 project1 코드가 실패합니다 (그 이유는 무엇이 project1인지 모르기 때문입니다). 해당 디렉토리에서 project1을 직접 설정하면 (즉, class2의 가져 오기는 from class1 import Class1 임) project2에서 project1을 패키지로 사용하려고하면 가져 오기가 실패합니다.

두 가지 방법이 있습니다 (project1을 패키지로 사용하고 패키지로 사용하지 마십시오)? 방법이 있다면, 실망스럽고 어쨌든 코드를 재구성해야합니까? 이걸 어떻게 처리해야하는지에 대한 다른 제안들? 감사!

편집 그냥, 분명히 문제 arrises class2subclass2 수입 때문에 할 차례 수입 class1인치 어떤 방법으로 class2을 가져 오는 경우 class1project2 또는 project1에서 가져 오기가 실패합니다. 즉, project1을 패키지로보고 다른 하나는 작업 디렉토리로 간주하기 때문입니다.

편집 2

내가 파이썬 3.5를 사용하고 있습니다. 외관상으로는 이것은 파이썬 2에서 작동하지만 파이썬의 현재 버전에서는 작동하지 않습니다.

+0

요청의 뉘앙스가 누락 된 것인지 잘 모르겠지만 'project1 import class1'을 사용하여 project1 클래스를 project2로 가져온 다음 class1.function()을 통해 코드를 사용할 수 있습니다. 각각의 파일에서'if __name__ == "__main __"'을 (를) 가지고 있어도 상관이 없습니다 ... class1을 class2로 가져 오는 것은 여전히'class1 import function'에서입니다. – chrxr

+0

@chrxr :'project2'에서'class2'를 가져 오려고하면 문제가 생깁니다. 'class2'는'class1'을 임포트하기 때문에 class2 내에서 import *를 어떻게 preform 할 것인가에 따라 import는'project2'의 관점에서 실패 할 것입니다 ('class1 import Class1'로부터 임포트한다면) 또는'project1' '(project1.class1 import class1'에서 가져올 경우). 이는 가져 오기 체인이 있기 때문입니다. 'subclass2' imports'class2'는'class1'을 수입합니다. –

+0

서브 모듈을 실행하려면'-m' 스위치를 사용해야합니다. 나는. 'python/path/to/my/package1/class1.py'를 실행하는 대신에'python -m package1.class1'을 실행해야합니다 (물론'package1' 패키지는'PYTHONPATH'에 있어야합니다. 그렇지 않으면 부모에 있어야합니다 예배 규칙서). 그건 그렇고, 나는 단순히 당신이하는 일을 피할 것입니다 : 클래스 정의와 스크립트를 명확하게 분리하고 결코'package1'을 실행하지 마십시오. 'package1'에서 클래스를 가져오고 수행해야 할 작업을 수행하는 * 별도의 * 파일을 작성하십시오. 간단하고 간단하며 오류가 발생하지 않는 파일 일뿐입니다. – Bakuriu

답변

0

당신은 project2 폴더에 설정된 현재 작업 디렉토리로 즉 project2 폴더 내부에서 class2.py를 실행할 수 있습니다 :

C:\...project2> python project1/class2.py 

을 또는 당신이 같을 것이다 창에

[email protected]:.../project2$ python project1/class2.py 

Python 경로를 내부에서 수정할 수 있습니다 class2.py :

import sys 
sys.path.append(".../project2") 

from project1.class1 import class1 

또는 PYTHONPATH 환경 변수를 비슷하게 수정하십시오.

것은 class2.py 예를 들면, 당신은 project2 항상 수입 경로를 시작 고려해야한다 subclass2.py에서 subclass1.py에서 예를 들어 뭔가를 프로젝트 가져 오기를 확장 할 수 있으려면 :

당연히
from project2.project1.class1 import class1 

당신이를 조정해야 방법은 방금 새로운 경로와 일치하는 것으로 나타났다.

+0

제안 해 주셔서 감사합니다. 불행히도, project1은 완전히 별개의 프로젝트이며 project2에 저장되지 않습니다 (실제로는 git submodule입니다). 또한 project2와의 연락이없는 유사한 방식으로 세 번째 프로젝트에서도 사용됩니다. 따라서 project1은 project2에 대한 참조가 없어야하며 그것에 대해 알 필요가 없습니다. project2만이 project1에 대해 알아야합니다. –

+0

그런 다음 첫 번째 방법은'PYTHONPATH' 환경 변수를 사용하고 여전히 유효한 옵션이어야합니다. – timakro

+0

네가 맞아 * * 작동 할거야. 하지만 부모 디렉토리의 코드를 실행하고 PYTHONPATH를 수동으로 편집하는 것이 약간의 문제이므로 답변으로 받아들이지 않을 것입니다. 이 코드는 팀원이 사용할 가능성이 높으며 이러한 접근 방식은 모두 약간의 예외이며 직관적이지는 않습니다. –

1

EDIT 2 : Python3 모듈 가져 오기가 작동하는 방식을 준수하도록 PYTHONPATH에 상위 디렉토리를 연결하는 class2.py의 코드가 추가되었습니다.

import sys 
import os 
sys.path.append(os.path.dirname(os.path.abspath(__file__))) 

Class1의 상대적 가져 오기가 제거되었습니다.

폴더 구조 :

project2 
    - class3.py 
    - project1 
    - __init__.py 
    - class1.py 
    - class2.py 

프로젝트 2/프로젝트 1/class1.py

class Class1(object): 
    def __init__(self): 
     super(Class1, self).__init__() 
     self.name = "DAVE!" 

    def printname(self): 
     print(self.name) 

def run(): 
    thingamy = Class1() 
    thingamy.printname() 

if __name__ == "__main__": 
    run() 

프로젝트 2/프로젝트 1/class2.py

import sys 
import os 
sys.path.append(os.path.dirname(os.path.abspath(__file__))) 

from class1 import Class1 

class Class2(Class1): 
    def childMethod(self): 
     print('Calling child method') 

def run(): 
    thingamy = Class2() 
    thingamy.printname() 
    thingamy.childMethod() 

if __name__ == "__main__": 
    run() 

프로젝트 2/CLA를 이 설정 클래스 1의 각각, 2, 3 독립형 스크립트로 실행할 수 있습니다으로

from project1.class2 import Class2 
from project1.class1 import Class1 

class Class3(Class2): 
    def anotherChildMethod(self): 
     print('Calling another child method') 

def run(): 
    thingamy = Class3() 
    thingamy.printname() 
    thingamy.anotherChildMethod() 

if __name__ == "__main__": 
    run() 

을 s3.py.

+0

이상한! 이것은 Python 2에서 작동하지만, Python 3에서 오류가 발생합니다! (즉,'ImportError : No module 'class1 '') (print 서술문을 갱신 할 때) 파이썬 3을 사용하고 있습니다. 나는 그것이 차이를 만들지 몰랐다. –

+0

즉, Python 2에 방금 게시 한 코드를 실행하면 원하는대로 모든 것이 작동합니다. 하지만 파이썬 3.5에서는 (print 문을 파이썬 3 구문에 맞게 수정 한 후에) 가져 오기 오류가 발생합니다. print 문 이외에 나는 코드를 조정하지 않았다. –

+0

Gotcha! class2.py에서 상대 가져 오기를 사용해야합니다. 이것은 Python3에 추가되어 가져 오기 위치의 모호성을 제거합니다. – chrxr