2012-12-13 7 views
7

"from"키워드를 사용하지 않고 import x를 사용하는 것이 한 가지 방법입니다. 그래서 네임 스페이스가있는 곳을 사방으로 참조하십시오.파이썬에서 순환 (순환) 가져 오기를 피합니까?

다른 방법이 있습니까? C와 같은 일을하는 것처럼 + + ifnotdef __b__ def __b__ 타입?

+2

순환 의존성이 없으며 y에서 x의 종속성을 결합하여 z를 만들고 x는 – Esailija

+0

인 y의 의존성을 나타냅니다.이 게시물은 중복입니다. http://stackoverflow.com/questions/744373/circular-or-cyclic -imports-in-python – alinsoar

+1

@alinsoar 정확한 복제본이 아닙니다.이 질문은 순환 수입이있을 때 어떻게 될지 질문했습니다. 이 질문은 그들을 피하는 기술을 요구합니다. –

답변

10

서로 의존하는 모든 모듈 쌍을 단일 모듈로 병합하십시오. 그런 다음 추가 모듈을 사용하여 이전 이름을 다시 가져옵니다.

예를 들면,

# a.py 
from b import B 

class A: whatever 

# b.py 
from a import A 

class B: whatever 

는 "코드 냄새"

# common.py 
class A: whatever 
class B: whatever 

# a.py 
from common import A 

# b.py 
from common import B 
+0

나는 당신이''common import A''와''common import B''를 의미한다고 생각하십니까? – jdi

+0

@ jdi : 예. 고마워, 고쳐. –

+21

이것은'a.py'와'b.py'보다는'common.py'에서 모든 것을 선언하도록 강제합니다. 좋은 해결책이 아닙니다. – Nick

5

원형 수입이 있습니다되고 자주 (항상은 아니지만) 리팩토링이 적합 할 것이라는 점을 나타냅니다. 예를 들어 A.xB.yB.y을 사용하는 경우 A.z을 사용하는 경우 A.z을 자체 모듈로 이동하는 것이 좋습니다.

원형 가져 오기가 필요하다고 생각되는 경우 일반적으로 모듈을 가져오고 정규화 된 이름 (예 : import A)을 사용하고 from A import x 대신 A.x을 사용하는 것이 좋습니다.

+1

명시 적 형식 검사를 수행하는 경우 어떻게해야합니까? 나는 고객이 이해하지 못하는 모호한 흔적이 아니라 매우 상세한 오류 메시지를 제공 할 수 있도록 지금 당장이를 시도하고있다. – Nick

0

from A import *을 시도하는 경우 대답은 매우 간단합니다. 그러지 마십시오. 일반적으로 이라고 가정하고import A으로하고 인증 된 이름을 참조하십시오.

빠른 스크립트 인 & 더티 스크립트와 대화식 세션은 완벽하게 합당한 일이지만,이 경우 원형 가져 오기가 실행되지 않습니다.

실제 코드에서 import *을 수행하는 것이 의미있는 경우가 있습니다. 예를 들어, 복잡하거나 동적으로 생성되거나 버전간에 자주 변경되는 모듈 구조를 숨기거나 너무 깊게 중첩 된 다른 사람의 패키지를 래핑하는 경우 import *은 "래퍼 모듈 "또는 최상위 패키지 모듈입니다. 하지만이 경우 가져올 항목이 없습니다.

사실, import *이 보증되고 순환 종속성이있는 경우를 상상할 수 없습니다.

from A import foo을 수행하는 경우 주위에 여러 가지 방법이 있습니다 (예 : , foo = A.foo). 그러나 당신은 아마 그것을하고 싶지 않습니다. 다시 말하지만, 실제로 네임 스페이스에 foo을 가져와야하는지 여부를 고려해보십시오. 정규화 된 이름은 기능이므로 해결할 문제는 아닙니다.

당신은 당신의 기능을 구현의 편의를 위해 from A import foo을하고 있다면, A 실제로 long_package_name.really_long_module_name과 코드 때문에 long_package_name.really_long_module_name.long_class_name.class_method_that_puts_me_over_80_characters에 대한 모든 호출의 읽을 수 있기 때문에, 당신은 항상 import long_package_name.really_long_module_name as P 다음 자격에 대한 P를 사용할 수있는 기억 전화. 누군가가 당신 상에 import * 않는 경우

(또한, 구현의 편의를 위해 수행 어떤 from와 함께, 당신은 아마 만들기 위해 __all__를 지정 있는지 확인하려면 기억하십시오 가져온 이름은 네임 스페이스의 일부가 표시되지 않습니다 대화 형 세션에서.)

또한 순환 종속성의 대부분은 아니지만 대부분의 경우가 잘못된 디자인의 증상이며 합리적인 방법으로 모듈을 리팩토링하면 문제가 해결 될 것이라고 지적한 바 있습니다. 드물게 이름을 네임 스페이스에 가져와 원형 모듈 집합이 실제로 가장 좋은 디자인 인 경우 일부 인공 리펙토링이 foo = A.foo보다 더 나은 선택 일 수 있습니다.