'모듈 가져 오기'또는 '모듈 가져 오기에서'를 사용 하시겠습니까?


411

사용하기에 가장 적합한 지 import module또는 from module import? 에 대한 포괄적 인 가이드를 찾으려고 노력했습니다 . 방금 Python으로 시작했으며 모범 사례를 염두에 두려고합니다.

기본적으로, 나는 누군가가 자신의 경험을 공유하고 다른 개발자가 선호하는 환경과 길을 잃지 않는 가장 좋은 방법은 무엇 입니까?


5
선택한 답변이 잘못되었다는 것을 알려 드리고자합니다. 차이가 주관적이지만 차이가 있음을 나타냅니다. 이로 인해 버그를 감지하기 어려울 수 있습니다. Michael Ray Lovetts의 답변을 참조하십시오.
Mayou36


2
특정 이름 식별자를 가져 오는 차이의 지옥있다 'from module import X,Y,Z대는'from module import * . 후자는 네임 스페이스를 오염시키고 모듈에서 일어나는 일에 따라 예기치 않은 결과를 줄 수 있습니다. 여전히 from module import *여러 모듈 을 사용하는 것이 더 나쁩니다 .
smci

답변:


474

import modulefrom module import foo주관적으로 차이가 있습니다. 가장 좋아하는 것을 골라 사용하십시오. 다음은 결정에 도움이되는 몇 가지 사항입니다.

import module

  • 장점 :
    • import진술의 유지 보수가 적습니다 . 모듈에서 다른 항목을 사용하기 위해 가져 오기를 추가 할 필요가 없습니다.
  • 단점 :
    • 입력하면 module.foo코드에서하는 것은 지루하고 중복 될 수 있습니다 (지루함을 사용하여 최소화 할 수 있습니다 import module as mo후 입력 mo.foo)

from module import foo

  • 장점 :
    • 사용하기에 적은 타이핑 foo
    • 액세스 할 수있는 모듈의 항목을보다 세밀하게 제어
  • 단점 :
    • 모듈에서 새 항목을 사용하려면 import명세서 를 업데이트해야 합니다
    • 에 대한 컨텍스트를 잃어 버립니다 foo. 예를 들어, 무엇에 ceil()비해 덜 명확 합니다math.ceil()

어느 방법이든 사용할 수 있지만를 사용 하지 마십시오 from module import *.

합리적인 대량의 코드 세트의 경우 import *모듈 에 코드를 시멘트로 만들면 제거 할 수 없습니다. 코드에서 사용되는 항목이 '모듈'에서 나오는 것을 결정하기가 어렵 기 때문에 import더 이상 사용하지 않는다고 생각하는 지점에 쉽게 도달 할 수는 있지만 확신하기가 매우 어렵습니다.


66
"from module import *"의 사용을 막기 위해 +1을 사용하면 네임 스페이스가 복잡해집니다.
Christian Witts

22
네임 스페이스를 복잡하게 만드는 것은 "import *"에서 가장 문제가되는 부분 이 아닙니다 . 가독성이 떨어집니다. 이름 충돌은 (단위) 테스트에서 나타납니다. 그러나 가져온 모듈에서 사용하는 모든 이름은 힌트가 될 것입니다. 나는 절대적으로 "import *"를 싫어한다.
Jürgen A. Erhard

21
파이썬의 선 (Zen)이 명시 적 (implicit)이 암시 적 (implicit)보다 낫다고 말하지 않습니까?
Antony Koch

8
from module import *다음과 같이 사용하면 특히 유용 할 수 있습니다 if(windows):\n\t from module_win import * \n else: \n\t from module_lin import *. 그런 다음 module_lin 및 module_win의 함수 이름이 동일한 이름을 갖는 경우 상위 모듈에 OS 독립 함수 이름이 포함될 수 있습니다. 조건부로 클래스를 상속받는 것과 같습니다.
anishsane

19
@anishsane. 다른 방법이 있습니다. module_win을 무언가로 가져옵니다. 그런 다음 항상 something.method_name ()을 사용하십시오
Vinay

163

모듈에 쓰는 것과 관련하여 언급되지 않은 또 다른 세부 사항이 있습니다. 이것이 일반적이지 않을 수도 있지만, 때때로 필요했습니다.

파이썬에서 참조 및 이름 바인딩이 작동하는 방식으로 인해 모듈 외부에서 foo.bar와 같은 모듈의 일부 기호를 업데이트하고 변경 사항을 "참조"하는 다른 가져 오기 코드가 있으면 foo a를 가져와야합니다. 특정 방식으로. 예를 들면 다음과 같습니다.

모듈 foo :

bar = "apples"

모듈 a :

import foo
foo.bar = "oranges"   # update bar inside foo module object

모듈 b :

import foo           
print foo.bar        # if executed after a's "foo.bar" assignment, will print "oranges"

그러나 모듈 이름 대신 기호 이름을 가져 오면 작동하지 않습니다.

예를 들어, 모듈 a에서 이것을하면 :

from foo import bar
bar = "oranges"

bar 설정이 모듈 a 내부의 "bar"이름에만 영향을 미치기 때문에 foo 모듈 객체에 "도달"하고 "bar"를 업데이트하지 않기 때문에 a 외부의 코드는 "오렌지"로 표시되지 않습니다.


마지막 예에서 여전히 'foo'내에서 'bar'를 업데이트하기 위해 'foo.bar = "orange"'를 호출 할 수 있습니까?
velocirabbit

4
아니요, 마지막 예에서 'foo'라는 이름을 알 수 없습니다.
Ghislain Leveque

31
이 답변은 질문에 대한 "진정한"답변을 제공합니다. 두 가지 수입 변형의 차이점
Mayou36

3
이 답변이 절대적으로 옳음을 증명하기 위해 약간의 스 니펫을 썼지 만 이것의 근거는 무엇입니까?
huangbeidu

나는 당신이 말하는 것은 지역 변수를 갖기 위해 심볼 이름을 가져 오지만 전역 변수를 갖기 위해 모듈 이름을 가져 오는 것이라고 생각하십니까 ???
WinEunuuchs2Unix

79

많은 사람들이 이미 importvs import from에 대해 설명했지만 , 후드에서 발생하는 일과 변경되는 모든 위치에 대해 조금 더 설명하려고합니다.


import foo:

를 가져 와서 foo현재 네임 스페이스에서 해당 모듈에 대한 참조를 만듭니다. 그런 다음 모듈 내부에서 특정 속성 또는 메소드에 액세스하려면 완료된 모듈 경로를 정의해야합니다.

foo.bar아니지만bar

from foo import bar:

을 가져 foo오고 나열된 모든 멤버에 대한 참조를 만듭니다 ( bar). 변수를 설정하지 않습니다 foo.

예 : bar하지만 bazfoo.baz

from foo import *:

를 가져 와서 foo현재 네임 스페이스에서 해당 모듈에 의해 정의 된 모든 공용 객체에 대한 참조를 만듭니다 (있는 __all__경우 나열된 __all__모든 것, 그렇지 않으면로 시작하지 않는 모든 것 _). 변수를 설정하지 않습니다 foo.

bar하고 baz아니라 _quxfoo._qux.


이제 우리가 할 때 보자 import X.Y:

>>> import sys
>>> import os.path

sys.modules이름 os과 확인 os.path:

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

검사 globals()locals()와 네임 스페이스 dicts osos.path:

 >>> globals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> locals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> globals()['os.path']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os.path'
>>>

위의 예 os에서 로컬 및 글로벌 네임 스페이스 에만 삽입 된 것을 발견했습니다 . 따라서 다음을 사용할 수 있어야합니다.

 >>> os
 <module 'os' from
  '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
 >>> os.path
 <module 'posixpath' from
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
 >>>

그러나 아닙니다 path.

>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

당신이 삭제되면 os현지인 () 네임 스페이스를, 당신은에 액세스 할 수 없습니다 os아니라으로 os.path그들이 sys.modules에 존재하더라도 :

>>> del locals()['os']
>>> os
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

이제 이야기 해 봅시다 import from:

from:

>>> import sys
>>> from os import path

확인 sys.modulesosos.path:

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

우리 sys.modules는 이전에 사용했던 것과 같은 것을 발견했습니다.import name

OK,하자 검사는이처럼 보이는 방법 locals()globals()dicts 네임 스페이스 :

>>> globals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> locals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['os']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os'
>>>

다음이 path아닌 이름을 사용하여 액세스 할 수 있습니다 os.path.

>>> path
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

에서 'path'를 삭제합시다 locals():

>>> del locals()['path']
>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

별명을 사용하는 마지막 예 :

>>> from os import path as HELL_BOY
>>> locals()['HELL_BOY']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['HELL_BOY']
<module 'posixpath' from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>

경로가 정의되어 있지 않습니다.

>>> globals()['path']
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 'path'
>>>

8
이것은 장황하지만, 이것은 상당히 복잡한 질문에 대한 목록에서 실제로 가장 좋은 대답입니다. 이 특정 문제에 대해 스타일보다 중요한 "언더 후드"미묘함을 설명하는 데 도움이되는 실제 코드를 제공합니다. 한 번 이상 공표 할 수 있기를 바랍니다!
Mike Williamson

사용 as SYMBOL하면이 답변의 작동 방식이 전혀 바뀌지 않습니까?
막시밀리안 버 즐리

40

두 가지 방법 모두 이유로 지원됩니다. 하나가 다른 것보다 더 적절한 경우가 있습니다.

  • import module: 모듈에서 많은 비트를 사용할 때 좋습니다. 단점은 각 참조를 모듈 이름으로 한정해야한다는 것입니다.

  • from module import ...: 가져온 항목은 모듈 이름 접두사없이 직접 사용할 수 있습니다. 단점은 사용하는 각 항목을 나열해야하며 코드의 출처가 명확하지 않다는 것입니다.

사용할 코드는 코드를 명확하고 읽기 쉽게 만드는 방법에 달려 있으며 개인 취향과 관련이 있습니다. import module코드에서 객체 또는 함수의 출처가 매우 명확하기 때문에 일반적으로 기울 입니다. 코드에서 from module import ...객체 / 함수를 많이 사용할 때 사용 합니다.


1
사용하는 방법이 from M import X어떻게 든 한정자를 사용하는 혜택을 여전히 수는? M.X수입 후에도 여전히 두 가지 이점을 모두 누릴 수있을 것 같습니다 .
절지 동물

@ artgropod : 킨다. 할 수 있습니다 class m: from something.too.long import x, y, z. 그래도 권장하지는 않습니다.
Lie Ryan

35

나는 항상 개인적으로 사용합니다

from package.subpackage.subsubpackage import module

그런 다음 모든 것에 액세스하십시오.

module.function
module.modulevar

그 이유는 짧은 호출이있는 동시에 각 루틴의 모듈 네임 스페이스를 명확하게 정의하기 때문입니다. 소스에서 지정된 모듈의 사용법을 검색해야하는 경우 매우 유용합니다.

말할 필요도없이, import *를 사용하지 마십시오. 네임 네임 스페이스를 오염시키고 주어진 함수가 어디에서 왔는지 알려주지 않기 때문에 (어떤 모듈에서)

물론 두 개의 다른 패키지에서 두 개의 다른 모듈에 대해 동일한 모듈 이름을 사용하면 문제가 발생할 수 있습니다.

from package1.subpackage import module
from package2.subpackage import module

이 경우 당연히 문제가 발생하지만 패키지 레이아웃에 결함이 있음을 암시하고 다시 생각해야합니다.


10
마지막 경우, 항상 다음을 사용할 수 있습니다 : import pkgN.sub.mod를 modN으로 각 모듈의 고유 한 이름을 지정하십시오. 'import modulename as mod1'패턴을 사용하여 긴 이름을 줄이거 나 단일 이름 변경으로 동일한 API (예 : DB API 모듈)의 구현간에 전환 할 수 있습니다.
Jeff Shannon

15
import module

모듈에서 많은 기능을 사용할 때 가장 좋습니다.

from module import function

필요할 때만 모듈에서 모든 함수와 유형으로 전역 네임 스페이스를 오염시키지 않으려는 경우에 가장 좋습니다 function.


7
'import module'을 수행하면 전역 네임 스페이스에서 유일한 것은 'module'입니까? 'from .. import *'를 수행하는 경우에만 네임 스페이스를 오염시킵니다.
John Fouhy

10

방금이 두 가지 방법 사이에 미묘한 차이가 있음을 발견했습니다.

모듈 foo이 다음 가져 오기를 사용하는 경우 :

from itertools import count

그러면 모듈 bar은 다음이 아닌에 count정의 된 것처럼 실수로 사용할 수 있습니다 .fooitertools

import foo
foo.count()

foo사용하는 경우 :

import itertools

실수는 여전히 가능하지만 그럴 가능성은 적습니다. bar할 필요가있다:

import foo
foo.itertools.count()

이로 인해 몇 가지 문제가 발생했습니다. 실수로 모듈을 정의하지 않은 모듈에서 예외를 가져 왔으며 다른 모듈에서만 가져 왔습니다 (사용하여 from module import SomeException). 가져 오기가 더 이상 필요하지 않고 제거되면 문제가되는 모듈이 손상되었습니다.


10

여기에 언급되지 않은 또 다른 차이점이 있습니다. 이것은 http://docs.python.org/2/tutorial/modules.html 에서 그대로 복사됩니다.

사용할 때

from package import item

항목은 패키지의 하위 모듈 (또는 하위 패키지)이거나 함수, 클래스 또는 변수와 같이 패키지에 정의 된 다른 이름 일 수 있습니다. import 문은 먼저 항목이 패키지에 정의되어 있는지 테스트합니다. 그렇지 않으면 모듈이라고 가정하고로드를 시도합니다. 찾지 못하면 ImportError 예외가 발생합니다.

반대로, 같은 구문을 사용할 때

import item.subitem.subsubitem

마지막을 제외한 각 항목은 패키지 여야합니다. 마지막 항목은 모듈 또는 패키지 일 수 있지만 이전 항목에서 정의 된 클래스 또는 함수 또는 변수 일 수 없습니다.


항목이 패키지 내부의 하위 모듈 인 경우 "패키지 가져 오기 항목에서"는 작동하지만 "가져 오기 패키지"package.item.subitem = ...은 빈 init .py 패키지에서 작동하지 않습니다. 패키지 의 init 파일에 "가져 오기 항목"이 있습니다.
Amitoz Dandiana

6

나는 초보자이기 때문에 간단한 방법으로 이것을 설명하려고 노력할 것입니다. 파이썬에는 다음과 같은 세 가지 유형의 import문장이 있습니다.

1. 일반 수입품 :

import math

이 유형의 임포트는 제가 개인적으로 좋아하는 것입니다.이 임포트 기술의 유일한 단점은 모듈의 기능을 사용해야 할 경우 다음 구문을 사용해야한다는 것입니다.

math.sqrt(4)

물론 타이핑 노력이 증가하지만 초보자는 모듈과 관련된 모듈과 기능을 추적하는 데 도움이됩니다 (좋은 텍스트 편집기를 사용하면 타이핑 노력이 크게 줄어들어 권장됩니다).

이 import 문을 사용하면 입력 노력을 더욱 줄일 수 있습니다.

import math as m

이제 사용하는 대신을 사용할 math.sqrt()수 있습니다 m.sqrt().

2. 기능 수입품 :

from math import sqrt

이 유형의 가져 오기는 코드가 모듈에서 하나 또는 몇 개의 함수에만 액세스해야하는 경우에 가장 적합하지만 모듈의 새 항목을 사용하려면 import 문을 업데이트해야합니다.

3. 범용 수입품 :

from math import * 

타이핑 노력을 크게 줄이지 만 모듈의 다양한 함수로 코드를 채우고 이름이 사용자 정의 함수의 이름과 충돌 할 수 있으므로 권장하지 않습니다. 예:

sqrt라는 이름의 함수가 있고 math를 가져 오는 경우 함수는 안전합니다. sqrt가 있고 math.sqrt가 있습니다. 그러나 math import *에서 할 경우 문제가 있습니다. 즉, 정확히 동일한 이름을 가진 두 개의 다른 함수입니다. 출처 : Codecademy


5
import package
import module

import토큰은 모듈 (Python 명령을 포함하는 파일) 또는 패키지 (파일을 포함하는 폴더) 여야 sys.path합니다 __init__.py.

서브 패키지가있는 경우 :

import package1.package2.package
import package1.package2.module

폴더 (패키지) 또는 파일 (모듈)에 대한 요구 사항은 동일하지만, 폴더 또는 파일 안에 있어야 package2하는 내부해야합니다 package1, 모두 package1하고 package2있어야합니다 __init__.py파일. https://docs.python.org/2/tutorial/modules.html

from수입의 스타일 :

from package1.package2 import package
from package1.package2 import module

패키지 또는 모듈은 import명령문을 포함하는 파일의 네임 스페이스를 대신 module(또는 package)로 입력합니다 package1.package2.module. 보다 편리한 이름에 항상 바인딩 할 수 있습니다.

a = big_package_name.subpackage.even_longer_subpackage_name.function

from가져 오기 스타일 만으로 특정 함수 또는 변수의 이름을 지정할 수 있습니다.

from package3.module import some_function

허용되지만

import package3.module.some_function 

허용되지 않습니다.


4

사람들이 말한 것을 더하기 위해 from x import *: 이름의 유래를 더 어렵게 만드는 것 외에도 Pylint와 같은 코드 검사기를 버립니다. 해당 이름을 정의되지 않은 변수로보고합니다.


3

이것에 대한 내 자신의 대답은 주로 몇 가지 다른 모듈을 사용할 것인지에 달려 있습니다. 하나 또는 두 개만 사용 하려는 경우 파일의 나머지 부분에서 키 입력 횟수가 줄어들 기 때문에 종종 from...을 사용 import하지만 많은 다른 모듈을 사용하려는 경우 import이는 각 모듈 참조가 자체 문서화됨을 의미하기 때문입니다. 사냥하지 않고도 각 심볼의 출처를 알 수 있습니다.

일반적으로 일반 가져 오기의 자체 문서화 스타일을 선호하고 ..로만 변경합니다. 가져올 모듈이 하나 뿐인 경우에도 모듈 이름을 입력해야하는 횟수가 10에서 20 이상으로 증가 할 때 가져 오기.


1

내가 알아 낸 중요한 차이 중 하나는 놀라 울 정도로 아무도 대해 이야기하고있다는 일반 사용하여 해당 수입 액세스 할 수있는 private variableprivate functions불가능 가져온 모듈에서 에서 가져 오기 문을.

여기에 이미지 설명을 입력하십시오

이미지 코드 :

setting.py

public_variable = 42
_private_variable = 141
def public_function():
    print("I'm a public function! yay!")
def _private_function():
    print("Ain't nobody accessing me from another module...usually")

plain_importer.py

import settings
print (settings._private_variable)
print (settings.public_variable)
settings.public_function()
settings._private_function()

# Prints:
# 141
# 42
# I'm a public function! yay!
# Ain't nobody accessing me from another module...usually

from_importer.py

from settings import *
#print (_private_variable) #doesn't work
print (public_variable)
public_function()
#_private_function()   #doesn't work

0

모듈 가져 오기-모듈에서 다른 것을 가져 오기 위해 추가 노력이 필요하지 않습니다. 중복 타이핑과 같은 단점이 있습니다.

모듈 가져 오기 시작-더 적은 입력 및 모듈의 어떤 항목에 액세스 할 수 있는지 제어합니다. 모듈에서 새 항목을 사용하려면 가져 오기 문을 업데이트해야합니다.


0

기본적으로 베어 함수 ( base64 , math , os , shutil , sys , time 등) 를 포함하는 일부 내장 모듈이 있으며 이러한 베어 함수 를 네임 스페이스에 바인딩 하여 가독성을 향상시키는 것이 좋습니다. 암호. 네임 스페이스없이 이러한 함수의 의미를 이해하는 것이 얼마나 어려운지 고려하십시오.

copysign(foo, bar)
monotonic()
copystat(foo, bar)

그들이 어떤 모듈에 묶여있을 때보 다 :

math.copysign(foo, bar)
time.monotonic()
shutil.copystat(foo, bar)

때로는 다른 모듈 간 충돌을 피하기 위해 네임 스페이스가 필요합니다 ( json.loadpickle.load )


반면에 대부분 클래스 ( configparser , datetime , tempfile , zipfile , ...) 를 포함하는 일부 모듈이 있으며 그 중 상당수는 클래스 이름을 충분히 설명 할 수있게합니다.

configparser.RawConfigParser()
datetime.DateTime()
email.message.EmailMessage()
tempfile.NamedTemporaryFile()
zipfile.ZipFile()

따라서 이러한 클래스를 코드에 추가 모듈 네임 스페이스와 함께 사용하면 새로운 정보가 추가되거나 코드가 길어질 지에 대한 논쟁이있을 수 있습니다.


0

가져 오기 호출 중에 고려해야 할 사항이 있습니다.

나는 다음과 같은 구조를 가지고 있습니다 :

mod/
    __init__.py
    main.py
    a.py
    b.py
    c.py
    d.py

main.py :

import mod.a
import mod.b as b
from mod import c
import d

dis.dis는 차이점을 보여줍니다.

  1           0 LOAD_CONST               0 (-1)
              3 LOAD_CONST               1 (None)
              6 IMPORT_NAME              0 (mod.a)
              9 STORE_NAME               1 (mod)

  2          12 LOAD_CONST               0 (-1)
             15 LOAD_CONST               1 (None)
             18 IMPORT_NAME              2 (b)
             21 STORE_NAME               2 (b)

  3          24 LOAD_CONST               0 (-1)
             27 LOAD_CONST               2 (('c',))
             30 IMPORT_NAME              1 (mod)
             33 IMPORT_FROM              3 (c)
             36 STORE_NAME               3 (c)
             39 POP_TOP

  4          40 LOAD_CONST               0 (-1)
             43 LOAD_CONST               1 (None)
             46 IMPORT_NAME              4 (mod.d)
             49 LOAD_ATTR                5 (d)
             52 STORE_NAME               5 (d)
             55 LOAD_CONST               1 (None)

결국 그들은 똑같아 보이지만 (STORE_NAME은 각 예에서 결과입니다), 다음 네 가지 순환 가져 오기를 고려해야 할 경우 주목할 가치가 있습니다.

예 1

foo/
   __init__.py
   a.py
   b.py
a.py:
import foo.b 
b.py:
import foo.a
>>> import foo.a
>>>

이 작동합니다

예 2

bar/
   __init__.py
   a.py
   b.py
a.py:
import bar.b as b
b.py:
import bar.a as a
>>> import bar.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "bar\a.py", line 1, in <module>
    import bar.b as b
  File "bar\b.py", line 1, in <module>
    import bar.a as a
AttributeError: 'module' object has no attribute 'a'

주사위 없음

예 3

baz/
   __init__.py
   a.py
   b.py
a.py:
from baz import b
b.py:
from baz import a
>>> import baz.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "baz\a.py", line 1, in <module>
    from baz import b
  File "baz\b.py", line 1, in <module>
    from baz import a
ImportError: cannot import name a

비슷한 문제 ...하지만 x 수입 y에서 분명히 수입 수입 xy와 y는 동일하지 않습니다.

예 4

qux/
   __init__.py
   a.py
   b.py
a.py:
import b 
b.py:
import a
>>> import qux.a
>>>

이것도 작동합니다


0

이것은 현재 디렉토리의 디렉토리 구조입니다.

.  
└─a  
   └─b  
     └─c
  1. import진술은 모든 중간 이름을 기억 합니다 .
    이 이름 자격 이 있어야합니다 .

    In[1]: import a.b.c
    
    In[2]: a
    Out[2]: <module 'a' (namespace)>
    
    In[3]: a.b
    Out[3]: <module 'a.b' (namespace)>
    
    In[4]: a.b.c
    Out[4]: <module 'a.b.c' (namespace)>
  2. from ... import ...문은 기억 만을 가져온 이름을 .
    이 이름 자격 이 없어야합니다 .

    In[1]: from a.b import c
    
    In[2]: a
    NameError: name 'a' is not defined
    
    In[2]: a.b
    NameError: name 'a' is not defined
    
    In[3]: a.b.c
    NameError: name 'a' is not defined
    
    In[4]: c
    Out[4]: <module 'a.b.c' (namespace)>

  • 참고 : 물론 1 단계와 2 단계 사이에서 Python 콘솔을 다시 시작했습니다.

0

얀 브로 벨 (Jan Wrobel)이 언급 했듯이 , 수입품의 다른 측면 중 하나는 수입품을 공개하는 방법입니다.

모듈 mymath

from math import gcd
...

mymath의 사용 :

import mymath
mymath.gcd(30, 42)  # will work though maybe not expected

gcd내부 용으로 만 가져 왔지만의 사용자에게 공개하지 않으면 mymath불편할 수 있습니다. 나는 이것을 자주 가지고 있으며, 대부분의 경우 "모듈을 깨끗하게 유지"하고 싶다.

Jan Wrobel 의 제안을 제외하고는 import math대신 이것을 사용하여 조금 더 모호하게 만드는 것 외에도 주요 밑줄을 사용하여 공개에서 수입을 숨기기 시작했습니다.

# for instance...
from math import gcd as _gcd
# or...
import math as _math

대규모 프로젝트에서이 "모범 사례"를 통해 후속 수입에 공개되는 내용과 그렇지 않은 내용을 정확하게 제어 할 수 있습니다. 이렇게하면 모듈이 깨끗하게 유지되고 특정 크기의 프로젝트에서 갚을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.