codememo

"수입*"이 나쁜 이유는 무엇입니까?

tipmemo 2023. 6. 17. 09:24
반응형

"수입*"이 나쁜 이유는 무엇입니까?

를 사용하지 않는 것이 좋습니다.import *파이썬으로

제가 다음에 하는 것을 피할 수 있도록 그 이유를 알려주실 수 있나요?

  • 네임스페이스에 많은 내용을 저장하기 때문입니다(이전 가져오기에서 다른 개체에 그림자를 드리울 수도 있지만 이에 대해 알지 못할 수도 있습니다).

  • 가져온 항목을 정확히 알 수 없고 어떤 모듈에서 가져온 특정 항목(가독성)을 쉽게 찾을 수 없기 때문입니다.

  • 왜냐하면 당신은 멋진 도구들을 사용할 수 없기 때문입니다.pyflakes코드의 오류를 정적으로 탐지합니다.

파이썬의 선에 따르면:

명시적인 것이 암시적인 것보다 낫습니다.

확실히 그것과 논쟁할 수 없습니까?

당신은 통과하지 못합니다.**locals()기능에 대해서요, 그렇죠?

Python에는 "포함" 문이 없기 때문에, 그리고self매개 변수는 명시적이고 범위 지정 규칙은 매우 간단합니다. 다른 모듈을 읽지 않고 IDE(어쨌든 언어가 매우 역동적이기 때문에 내성 방식으로 제한됨) 없이 변수를 손가락으로 가리키고 해당 개체가 어디서 왔는지 말하는 것은 일반적으로 매우 쉽습니다.

import *그 모든 것을 깨뜨립니다.

또한, 그것은 벌레를 숨길 수 있는 구체적인 가능성을 가지고 있습니다.

import os, sys, foo, sqlalchemy, mystuff
from bar import *

바 에 "제바모다음중하있으이면나가에듈"가 있으면,os", "mystuff으로 가져온 속성을하고 매우 .속성은 명시적으로 가져온 속성을 재정의하고 매우 다른 것을 가리킬 수 있습니다.__all__in bar는 종종 현명합니다 - 이것은 암시적으로 가져올 것을 명시합니다 - 그러나 여전히 bar 모듈을 읽고 구문 분석하지 않고는 객체가 어디에서 왔는지 추적하기 어렵습니다.네트워크import *프로젝트의 소유권을 가질 때 가장 먼저 수정하는 것입니다.

: 에 오마해지: 에약만.import *하지만 그것은 조심스럽게 사용되어야 합니다.다른 모듈 위에 전면 인터페이스를 제공하는 것이 좋은 사용 사례입니다.마찬가지로 조건부 가져오기 문을 사용하거나 함수/클래스 네임스페이스 내부 가져오기를 사용하려면 약간의 규율이 필요합니다.

저는 중간 규모에서 큰 프로젝트나 여러 기여자가 있는 소규모 프로젝트에서 최소한의 위생 상태가 필요하다고 생각합니다. 적어도 파이플레이크를 실행하거나 적절하게 구성된 파일린트를 실행하는 것과 같은 통계적 분석의 관점에서 그것들이 발생하기 전에 여러 종류의 벌레를 잡는 것입니다.

물론 이것은 파이썬이기 때문에 자유롭게 규칙을 어기고 탐색할 수 있습니다. 하지만 10배로 성장할 수 있는 프로젝트에 주의하십시오. 소스 코드에 규율이 없다면 문제가 될 것입니다.

이는 네임스페이스를 오염시키고 있기 때문입니다.사용자가 직접 정의한 함수와 충돌할 수 있는 고유 네임스페이스의 모든 함수 및 클래스를 가져옵니다.

또한, 유지보수 작업에는 정규화된 이름을 사용하는 것이 더 명확하다고 생각합니다. 코드 라인 자체에서 함수의 출처를 확인할 수 있으므로 문서를 훨씬 쉽게 확인할 수 있습니다.

모듈 foo:

def myFunc():
    print 1

코드에서:

from foo import *

def doThis():
    myFunc() # Which myFunc is called?

def myFunc():
    print 2

.from ... import *대화형 세션에서.

foo라는 모듈에 다음 코드가 있다고 가정합니다.

import ElementTree as etree

자신의 모듈에는 다음과 같은 기능이 있습니다.

from lxml import etree
from foo import *

이제 lxml의 트리가 있는 것처럼 보이지만 실제로 Element가 있는 디버깅하기 어려운 모듈이 있습니다.대신 나무.

사람들이 여기에 제시한 유효한 요점을 이해했습니다.하지만, 저는 때때로 "스타 가져오기"가 항상 나쁜 관행이 아닐 수도 있다는 한 가지 주장을 가지고 있습니다.

  • 가 다든상수같라는 때const.py:
    • 내가 하면,import const그러면 모든 상수에 대해, 나는 그것을 다음과 같이 언급해야 합니다.const.SOMETHING가장 편리한 방법은 아닐 겁니다
    • 내가 하면,from const import SOMETHING_A, SOMETHING_B ...분명히 너무 장황해서 구조의 목적을 달성할 수 없습니다.
    • 그래서 나는 이 경우에, 하는 것을 느낍니다.from const import *더 나은 선택일 수도 있습니다.

http://docs.python.org/tutorial/modules.html

으로 일적으수방법은는입을 수입하는 하십시오.*가독성이 떨어지는 코드를 유발하는 경우가 많기 때문에 모듈 또는 패키지에서 이를 확인할 수 없습니다.

이것들은 모두 좋은 대답입니다.새로운 사람들에게 파이썬에서 코딩을 가르치고 처리할 때 추가할 것입니다.import *매우 어렵습니다.당신이나 그들이 코드를 작성하지 않았더라도, 그것은 여전히 걸림돌입니다.

저는 아이들(약 8세)에게 파이썬으로 프로그래밍하여 마인크래프트를 조작하도록 가르칩니다.저는 그들에게 (Atom Editor)와 협력하고 (bpython을 통해) REPL 기반 개발을 가르칠 수 있는 유용한 코딩 환경을 제공하고 싶습니다.아톰에서는 힌트/완성이 bpython만큼 효과적으로 작동한다는 것을 발견했습니다.운 좋게도, 다른 통계 분석 도구들과 달리, 아톰은 속지 않았습니다.import *.

하지만, 이 예를 들어 보겠습니다... 포장지에서 그들은from local_module import *블록 목록을 포함하는 일괄 모듈.네임스페이스 충돌 위험은 무시해 보겠습니다.함으로써from mcpi.block import *그들은 사용 가능한 것이 무엇인지 알기 위해 당신이 살펴봐야 하는 모호한 유형의 블록의 전체 목록을 만듭니다.에 약그들이대사면다용했신만면다사▁used▁if▁they▁had를 사용했다면.from mcpi import block그런 다음 입력할 수 있습니다.walls = block.자동 완성 목록이 팝업됩니다.Atom.io screenshot

이는 두 가지 이유로 매우 나쁜 관행입니다.

  1. 코드 가독성
  2. 변수/함수 등을 재정의할 위험

포인트 1: 예를 들어 보겠습니다.

from module1 import *
from module2 import *
from module3 import *

a = b + c - d

를 보면 도 알 수 .b,c그리고.d사실은 소속된 것입니다.

반대로 다음과 같이 하면 됩니다.

#                   v  v  will know that these are from module1
from module1 import b, c   # way 1
import module2             # way 2

a = b + c - module2.d
#            ^ will know it is from module2

그것은 당신에게 훨씬 더 깨끗하며, 또한 당신의 팀에 새로 합류한 사람이 더 좋은 생각을 할 것입니다.

포인트 2: 두 가지 모두를 말합니다.module1그리고.module2가 서변수 있다습니가로로 되어 .b할 때: 가할때내때:

from module1 import *
from module2 import *

print b  # will print the value from module2

에 은다 음과같다니습의 .module1분실되었습니다.코드가 작동하지 않는 이유를 디버깅하는 것은 어려울 것입니다.b는 에선됨으로 됩니다.module1그리고 나는 내 코드가 사용될 것으로 예상하여 코드를 작성했습니다.module1.b

다른 모듈에 동일한 변수가 있고 전체 모듈을 가져오지 않으려면 다음 작업을 수행할 수도 있습니다.

from module1 import b as mod1b
from module2 import b as mod2b

테스트를 위해 "A1"과 "B1"을 각각 출력하는 2개의 기능 A와 B로 구성된 모듈 test.py 을 만들었습니다.다음과 함께 test.py 을 가져온 후:

import test

저는 두 가지 기능을 테스트로 실행할 수 있습니다.A() 및 테스트.B() 및 "test"는 네임스페이스에 모듈로 표시되므로 test.py 을 편집하면 다음을 사용하여 다시 로드할 수 있습니다.

import importlib
importlib.reload(test)

하지만 제가 다음과 같은 일을 한다면,

from test import *

네임스페이스에 "테스트"에 대한 참조가 없으므로 대화형 세션에서 문제가 되는 편집 후 다시 로드할 방법이 없습니다.반면에 다음 중 하나는.

import test
import test as tt

에서는 네임스페이스에 "test" 또는 "tt"(각각)를 모듈 이름으로 추가하므로 다시 로드할 수 있습니다.

내가 할 경우:

from test import *

이름 "A"와 "B"는 함수로 네임스페이스에 표시됩니다.test.py 을 편집하고 위의 명령을 반복해도 수정된 버전의 함수가 다시 로드되지 않습니다.

다음 명령을 실행하면 오류 메시지가 나타납니다.

importlib.reload(test)    # Error - name 'test' is not defined

"from module import *"로 로드된 모듈을 다시 로드하는 방법을 아는 사람이 있다면 게시하십시오.그렇지 않으면 이 양식을 사용하지 않는 또 다른 이유가 됩니다.

from module import *

은 절대로 ( 사용해서는 안 .import *생산 코드로

을 가져오는 *모듈에서 불량, 패키지에서 *을(를) 가져오는 것은 아마도 더 나쁠 것입니다.

기적으로본,from package import *패지에의정이름가져로 .__init__.py이전 문에 의해 로드된 패키지의 하위 모듈을 포함합니다.

패지가인 __init__.py코드는 이름이 붙은 목록을 정의합니다.__all__다음과 같은 경우에 가져올 하위 모듈 이름의 목록으로 간주됩니다.from package import *가 발생했습니다.

이이 예를 들어 '이'가 하면).__all__에정된에 정의되어 .sound/effects/__init__.py):

# anywhere in the code before import *
import sound.effects.echo
import sound.effects.surround

# in your module
from sound.effects import *

은 마막문다가다니져옵음을을 입니다.echo그리고.surround (전정의다우선보함에스)에 정의되어 있기 네임스페이스로 정의를 함)sound.effects▁▁when에간 때 패키지import문이 실행됩니다.

언급URL : https://stackoverflow.com/questions/2386714/why-is-import-bad

반응형