'모듈 가져 오기'또는 '모듈 가져 오기에서'를 사용 하시겠습니까?
사용하기에 가장 적합한 지 import module
또는 from module import
? 에 대한 포괄적 인 가이드를 찾으려고 노력했습니다 . 방금 Python으로 시작했으며 모범 사례를 염두에 두려고합니다.
기본적으로, 나는 누군가가 자신의 경험을 공유하고 다른 개발자가 선호하는 환경과 길을 잃지 않는 가장 좋은 방법은 무엇 입니까?
import module
와 from 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
더 이상 사용하지 않는다고 생각하는 지점에 쉽게 도달 할 수는 있지만 확신하기가 매우 어렵습니다.
모듈에 쓰는 것과 관련하여 언급되지 않은 또 다른 세부 사항이 있습니다. 이것이 일반적이지 않을 수도 있지만, 때때로 필요했습니다.
파이썬에서 참조 및 이름 바인딩이 작동하는 방식으로 인해 모듈 외부에서 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 외부의 코드는 "오렌지"로 표시되지 않습니다.
많은 사람들이 이미 import
vs import from
에 대해 설명했지만 , 후드 아래에서 발생하는 일과 변경되는 모든 위치에 대해 조금 더 설명하려고합니다.
import foo
:
를 가져 와서 foo
현재 네임 스페이스에서 해당 모듈에 대한 참조를 만듭니다. 그런 다음 모듈 내부에서 특정 속성 또는 메소드에 액세스하려면 완료된 모듈 경로를 정의해야합니다.
예 foo.bar
아니지만bar
from foo import bar
:
을 가져 foo
오고 나열된 모든 멤버에 대한 참조를 만듭니다 ( bar
). 변수를 설정하지 않습니다 foo
.
예 : bar
하지만 baz
나foo.baz
from foo import *
:
를 가져 와서 foo
현재 네임 스페이스에서 해당 모듈에 의해 정의 된 모든 공용 객체에 대한 참조를 만듭니다 (있는 __all__
경우 나열된 __all__
모든 것, 그렇지 않으면로 시작하지 않는 모든 것 _
) 변수를 설정하지 않습니다 foo
.
예 bar
하고 baz
아니라 _qux
나 foo._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 os
및 os.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.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'>
우리 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'
>>>
두 가지 방법 모두 이유로 지원됩니다. 하나가 다른 것보다 더 적절한 경우가 있습니다.
import module
: 모듈에서 많은 비트를 사용할 때 좋습니다. 단점은 각 참조를 모듈 이름으로 한정해야한다는 것입니다.from module import ...
: 가져온 항목은 모듈 이름 접두사없이 직접 사용할 수 있습니다. 단점은 사용하는 각 항목을 나열해야하며 코드의 출처가 명확하지 않다는 것입니다.
사용할 코드는 코드를 명확하고 읽기 쉽게 만드는 방법에 따라 다르며 개인 취향과 관련이 있습니다. import module
코드에서 객체 또는 함수의 출처가 매우 명확하기 때문에 일반적으로 기울 입니다. 코드에서 from module import ...
객체 / 함수를 많이 사용할 때 사용 합니다.
나는 개인적으로 항상 사용
from package.subpackage.subsubpackage import module
그런 다음 모든 것에 액세스하십시오.
module.function
module.modulevar
그 이유는 짧은 호출이있는 동시에 각 루틴의 모듈 네임 스페이스를 명확하게 정의하기 때문입니다. 소스에서 지정된 모듈의 사용법을 검색해야하는 경우 매우 유용합니다.
말할 필요도없이 import *를 사용하지 마십시오. 네임 네임 스페이스를 오염시키고 주어진 함수가 어디에서 왔는지 알려주지 않기 때문에 (어떤 모듈에서)
물론 두 개의 서로 다른 패키지에서 두 개의 서로 다른 모듈에 대해 동일한 모듈 이름을 사용하면 문제가 발생할 수 있습니다.
from package1.subpackage import module
from package2.subpackage import module
이 경우 당연히 문제가 발생하지만 패키지 레이아웃에 결함이 있음을 암시하고 다시 생각해야합니다.
import module
모듈에서 많은 기능을 사용할 때 가장 좋습니다.
from module import function
필요할 때만 모듈에서 모든 함수와 유형으로 전역 네임 스페이스를 오염시키지 않으려는 경우에 가장 좋습니다 function
.
방금이 두 가지 방법 사이에 미묘한 차이가 있음을 발견했습니다.
모듈 foo
이 다음 가져 오기를 사용하는 경우 :
from itertools import count
그러면 모듈 bar
은 다음이 아닌에 count
정의 된 것처럼 실수로 사용할 수 있습니다 .foo
itertools
import foo
foo.count()
foo
사용하는 경우 :
import itertools
실수는 여전히 가능하지만 그럴 가능성은 적습니다. bar
할 필요가있다:
import foo
foo.itertools.count()
이로 인해 몇 가지 문제가 발생했습니다. 실수로 모듈을 정의하지 않은 모듈에서 예외를 가져 왔으며 다른 모듈에서만 가져 왔습니다 (사용하여 from module import SomeException
). 가져 오기가 더 이상 필요하지 않고 제거되면 문제가되는 모듈이 손상되었습니다.
여기에 언급되지 않은 또 다른 차이점이 있습니다. 이것은 http://docs.python.org/2/tutorial/modules.html 에서 그대로 복사됩니다.
사용할 때
from package import item
항목은 패키지의 하위 모듈 (또는 하위 패키지)이거나 함수, 클래스 또는 변수와 같이 패키지에 정의 된 다른 이름 일 수 있습니다. import 문은 먼저 항목이 패키지에 정의되어 있는지 테스트합니다. 그렇지 않은 경우, 모듈이라고 가정하고로드를 시도합니다. 찾지 못하면 ImportError 예외가 발생합니다.
반대로, 같은 구문을 사용할 때
import item.subitem.subsubitem
마지막을 제외한 각 항목은 패키지 여야합니다. 마지막 항목은 모듈 또는 패키지 일 수 있지만 이전 항목에서 정의 된 클래스 또는 함수 또는 변수 일 수 없습니다.
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
허용되지 않습니다.
나는 초보자이기 때문에 간단한 방법으로 이것을 설명하려고 노력할 것입니다. 파이썬에는 다음과 같은 세 가지 유형의 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
사람들이 말한 것을 더하기 위해 from x import *
: 이름의 유래를 더 어렵게 만드는 것 외에도 Pylint와 같은 코드 검사기를 버립니다. 해당 이름을 정의되지 않은 변수로보고합니다.
이것에 대한 내 자신의 대답은 주로 사용할 모듈의 수에 달려 있습니다. 하나 또는 두 개만 사용 하려는 경우 파일의 나머지 부분에서 키 입력 횟수가 줄어들 기 때문에 종종 from
...을 사용 import
하지만 많은 다른 모듈을 사용하려는 경우 import
이는 각 모듈 참조가 자체 문서화됨을 의미하기 때문입니다. 사냥 할 필요없이 각 심볼의 출처를 알 수 있습니다.
자주 가져 오기의 자체 문서화 스타일을 선호하고 ..로만 변경합니다. 가져 오는 모듈이 하나 뿐인 경우에도 모듈 이름을 입력해야하는 횟수가 10에서 20 이상으로 증가 할 때 가져 오기.
내가 알아 낸 중요한 차이 중 하나는 놀라 울 정도로 아무도 대해 이야기하고있다는 일반 사용하여 해당 수입 액세스 할 수있는 private variable
및 private 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
모듈 가져 오기-모듈에서 다른 것을 가져 오기 위해 추가 노력이 필요하지 않습니다. 중복 타이핑과 같은 단점이 있습니다.
모듈 가져 오기 시작-입력 횟수를 줄이며 모듈의 어떤 항목에 액세스 할 수 있는지 제어합니다. 모듈에서 새 항목을 사용하려면 가져 오기 문을 업데이트해야합니다.
기본적으로 베어 함수 ( base64 , math , os , shutil , sys , time 등) 를 포함하는 일부 내장 모듈이 있으며 이러한 베어 함수 를 네임 스페이스에 바인딩 하여 가독성을 향상시키는 것이 좋습니다. 암호. 네임 스페이스없이 이러한 함수의 의미를 이해하는 것이 얼마나 어려운지 고려하십시오.
copysign(foo, bar)
monotonic()
copystat(foo, bar)
그들이 어떤 모듈에 묶여있을 때보 다 :
math.copysign(foo, bar)
time.monotonic()
shutil.copystat(foo, bar)
때로는 다른 모듈 간 충돌을 피하기 위해 네임 스페이스가 필요합니다 ( json.load 대 pickle.load )
반면에 대부분 클래스 ( configparser , datetime , tempfile , zipfile , ...) 를 포함하는 일부 모듈이 있으며 그 중 상당수는 클래스 이름을 충분히 설명 할 수 있습니다.
configparser.RawConfigParser()
datetime.DateTime()
email.message.EmailMessage()
tempfile.NamedTemporaryFile()
zipfile.ZipFile()
따라서 이러한 클래스를 코드에 추가 모듈 네임 스페이스와 함께 사용하면 새로운 정보가 추가되거나 코드가 길어질 지에 대한 논쟁이있을 수 있습니다.
가져 오기 호출 중에 고려해야 할 사항이 있습니다.
나는 다음과 같은 구조를 가지고 있습니다 :
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
>>>
이것도 작동합니다
참고 URL : https://stackoverflow.com/questions/710551/use-import-module-or-from-module-import
'Programing' 카테고리의 다른 글
예외를 일으킨 예외 설명 및 스택 추적을 모두 문자열로 가져옵니다. (0) | 2020.02.29 |
---|---|
내용으로 div의 높이를 확장하십시오. (0) | 2020.02.29 |
R에 어떤 패키지 버전이로드되어 있는지 확인하는 방법 (0) | 2020.02.29 |
파일 변환 : Android에서 Uri를 파일로 (0) | 2020.02.29 |
LINQ를 사용하여 목록을 하위 목록으로 분할 (0) | 2020.02.29 |