Python에서 순환 가져 오기 오기를 피하는 방법은 무엇입니까? [복제]
나는 순환에서 순환 수입 문제가 이전에 여러 번 제기하고 있다는 것을 읽었습니다. 이 토론에서 반복적으로 언급되는 의견은 순환 가져 오는 잘못된 디자인의 신호는 순환 가져 오기를 피하기 위해 코드를 순환 가져옵니다.
누군가가 상황에서 순환 가져 오기를 피하는 방법을 알려줄 수 있습니까? : 두 개의 클래스가있는 클래스가 다른 클래스의 인스턴스를 가져 와서 클래스의 인스턴스를 반환하는 생성자 (메소드)를 갖기를 원합니다.
보다 구체적으로, 하나의 클래스는 변경이 가능하고 다른 하나는 변경이 불가능합니다. 불변 클래스는 해싱, 비교가 필요합니다. 변경 가능한 클래스도 작업을 수행하는 데 필요합니다. 이 세트 및 frozensets 또는 목록 및 튜플과 유사합니다.
두 클래스 정의를 동일한 모듈에 넣을 수 있습니다. 다른 제안이 있습니까?
장난감 예제는 목록 인 속성을 가진 클래스 A와 튜플 인 속성을 가진 클래스 B입니다. 그런 다음 클래스 A에는 클래스 B의 인스턴스를 사용하고 클래스 A의 인스턴스를 반환하는 메서드가 표시됩니다 (튜플을 목록으로 변환하여) 유사하게 B 클래스 A의 인스턴스를 가져와 클래스 B의 인스턴스를 반환하는 메서드가 있습니다. (목록을 튜플로 변환하여).
모듈 만 가져오고 모듈에서 가져 오지 마세요.
고려 a.py
:
import b
class A:
def bar(self):
return b.B()
및 b.py
:
import a
class B:
def bar(self):
return a.A()
이것은 완벽하게 작동합니다.
다음 예제 표준 패키지를 고려 곳 a.py
과 b.py
서로에 따라 달라집니다
/package
__init__.py
a.py
b.py
여러 가지가 있습니다.
import package.a # Absolute import
import package.a as a_mod # Absolute import bound to different name
from package import a # Alternate absolute import
import a # Implicit relative import (deprecated, py2 only)
from . import a # Explicit relative import
불행하게도, 단지 1, 4 옵션이 순환 휴식이 작동합니다 (모든 인상 ImportError
또는 AttributeError
). 일반적으로 네 번째 구문은 python2에서만 작동하고 다른 세입자 모듈과 충돌 할 위험이 있으므로 사용하지 않습니다. 실제로 첫 번째 구문 만 작동 보장됩니다. 그러나 순환 옵션을 처리 할 때 여전히 몇 가지 옵션이 있습니다.
편집 :
ImportError
및AttributeError
문제는 2에서만 발생합니다. 오기 3에서는 기계가 다시 작성되는 가져 오기 오기 문 (4 제외)은 순환이 있어도 작동합니다.
절대 가져 오기 오기 사용
위의 첫 번째 가져 오기 구문을 사용하십시오. 이 방법의 단점 은 큰 패키지의 경우 가져 오기 이름이 매우 길어질 수있는 것 입니다.
에 a.py
import package.b
에 b.py
import package.a
나중에 가져 오기 오기 연기
이 방법이 많은 것을 사용하는 것이지만 여전히 나에게 엉뚱한 느낌이 들며 모든 것이 상단을 볼 수없고 모든 모듈을 볼 수있는 것이 많은 점이 마음에 들었습니다. 모든 기능을 검색해야합니다. 매일.
에 a.py
def func():
from package import b
에 b.py
def func():
from package import a
모든 가져 오기 오기를 중앙 모듈에 배치
이것은 또한 작동하지만 모든 패키지 및 하위 모듈 호출이 매우 길어 지는 첫 번째 방법과 동일한 문제가 있습니다. 또한 두 가지 주요 결함 이 있습니다. 하나 또는 두 개만 사용하는 경우에도 모든 하위 모듈 을 강제 로 가져 오지만 여전히 하위 모듈을 볼 수없고 해당 종속성이 맨 위에 표시됩니다. 기능을 살펴 봐야합니다.
에 __init__.py
from . import a
from . import b
에 a.py
import package
def func():
package.b.some_object()
에 b.py
import package
def func():
package.a.some_object()
그래서 그것들은 당신의 선택입니다 (그리고 그들은 모두 IMO를 짜증나게합니다). 솔직히 이것은 파이썬 가져 오기 기계에서 눈부신 버그 인 것 같지만 제 의견입니다.
우리는 더 나은 읽기와 더 짧은 액세스 문자열을 위해 절대 수입과 함수의 조합을 수행합니다.
- 장점 : 순수 절대 가져 오기에 비해 더 짧은 액세스 문자열
- 단점 : 추가 함수 호출로 인해 약간 더 많은 오버 헤드
main / sub / a.py
import main.sub.b
b_mod = lambda: main.sub.b
class A():
def __init__(self):
print('in class "A":', b_mod().B.__name__)
main / sub / b.py
import main.sub.a
a_mod = lambda: main.sub.a
class B():
def __init__(self):
print('in class "B":', a_mod().A.__name__)
참고 URL : https://stackoverflow.com/questions/7336802/how-to-avoid-circular-imports-in-python
'IT' 카테고리의 다른 글
명령 줄에서 XLS를 CSV로 변환 (0) | 2020.08.27 |
---|---|
같은 줄에 에코를 표시하고 업데이트하는 방법 (0) | 2020.08.27 |
첫 번째 마이너스와 마지막 마이너스의 CSS 선택기 (0) | 2020.08.27 |
TimeStamp를 Java에서 날짜로 변환하는 방법은 무엇입니까? (0) | 2020.08.27 |
node.js에서 어디에서 있습니까의 sha1 해시를 어떻게 얻을 수 있습니까? (0) | 2020.08.27 |