답변:
이것은 파이썬과 관련이 없습니다. 전역 변수는 모든 프로그래밍 언어에서 좋지 않습니다.
그러나 전역 상수 는 개념적으로 전역 변수 와 동일하지 않습니다 . 전역 상수는 완벽하게 무해합니다. 파이썬에서 둘 사이의 구별은 순전히 관례에 따라 : CONSTANTS_ARE_CAPITALIZED
and globals_are_not
.
전역 변수가 나쁜 이유는 함수가 부작용을 숨겨서 (명백하지 않고, 놀랍고, 감지하기 어렵고, 진단하기 어렵게하여) 복잡성을 증가시켜 잠재적으로 Spaghetti 코드로 이어질 수 있기 때문 입니다.
그러나 알고리즘 최적화, 복잡성 감소, 캐싱 및 메모 화 또는 주로 명령형 코드베이스에서 시작된 포팅 구조의 실용성을 위해 함수 프로그래밍에서도 전역 상태의 정상적인 사용이 허용됩니다 (로컬 상태 및 가변성).
대체로 귀하의 질문에 여러 가지 방법으로 답변 할 수 있으므로 가장 좋은 방법은 Google "전역 변수가 왜 나쁜지"라는 것입니다. 몇 가지 예 :
더 깊이 들어가서 부작용이 왜 전부인지, 그리고 다른 많은 계몽적인 것들을 알고 싶다면 함수형 프로그래밍을 배워야합니다.
예, 이론적 으로 글로벌 (및 일반적으로 "상태")은 악합니다. 실제로 파이썬의 패키지 디렉토리를 살펴보면 대부분의 모듈이 전역 선언으로 시작한다는 것을 알 수 있습니다. 분명히 사람들은 그들에게 아무런 문제가 없습니다.
특히 파이썬의 경우 전역의 가시성은 모듈로 제한됩니다. 따라서 전체 프로그램에 영향을 미치는 "진정한"전역이 없으므로 덜 해 롭습니다. 또 다른 요점은 없습니다 const
. 따라서 상수가 필요할 때 전역을 사용해야합니다.
내 실습에서 함수에서 전역을 수정하면 global
기술적으로 필요하지 않더라도 항상 다음과 같이 선언합니다 .
cache = {}
def foo(args):
global cache
cache[args] = ...
이것은 전역의 조작을 추적하기 쉽게 만듭니다.
이 주제에 대한 개인적인 의견은 함수 논리에서 전역 변수를 사용한다는 것은 다른 코드가 해당 함수의 논리와 예상 출력을 변경하여 디버깅을 매우 어렵게 만들고 (특히 대규모 프로젝트에서) 테스트를 더 어렵게 만들 수 있음을 의미한다는 것입니다. 게다가.
또한, 다른 사람들이 여러분의 코드를 읽는 것을 고려한다면 (오픈 소스 커뮤니티, 동료 등) 전역 변수가 설정되는 위치, 변경된 위치 및 반대되는이 전역 변수에서 무엇을 기대해야하는지 이해하는 데 어려움을 겪을 것입니다. 함수 정의 자체를 읽어 그 기능을 결정할 수있는 격리 된 함수로.
깨끗하고 (거의) 버그가없는 코드는 가능한 한 순수한 함수를 가져야한다고 생각합니다 ( 순수 함수 참조 ). 순수 함수는 다음과 같은 조건을 가진 함수입니다.
전역 변수를 갖는 것은 외부 코드로 둘 다 아닌 경우 위 중 하나 이상을 위반하면 예상치 못한 결과가 발생할 수 있습니다.
순수 함수의 또 다른 명확한 정의 : "순수 함수는 모든 입력을 명시 적 인수로 취하고 모든 출력을 명시 적 결과로 생성 하는 함수입니다 ." [1] . 전역 변수를 갖는 것은 입력과 출력 중 하나 (전역 변수)가 명시 적으로 제공되거나 반환되지 않기 때문에 순수 함수의 개념을 위반합니다.
당신이 단위 테스트 및 첫 번째 원칙을 고려하는 경우 또한 그에, ( F의 AST 검사, I ndependent 테스트, R의 epeatable을, S 엘프 - 검증 및 T imely)는 독립적 인은 (원칙적으로 테스트 위반 아마되는 테스트 의존하지 않는 방법 서로).
전역 변수 (항상 그런 것은 아님)가 있지만 대부분의 경우 (적어도 지금까지 본 것 중)은 결과를 준비하고 다른 함수에 전달하는 것입니다. 이것은 또한이 원칙에 위배됩니다. 전역 변수가 그런 방식으로 사용 되었다면 (즉, 함수 X에서 사용되는 전역 변수가 먼저 함수 Y에서 설정되어야 함) 단위 테스트 함수 X에 대해 테스트 / 실행 함수 Y를 먼저 실행해야 함을 의미합니다.
다른 한편으로 다른 사람들이 이미 언급했듯이 전역 변수가 "상수"변수로 사용되면 언어가 상수를 지원하지 않기 때문에 약간 더 나을 수 있습니다. 그러나 저는 항상 클래스로 작업하고 "상수"를 클래스 멤버로 사용하고 전역 변수를 전혀 사용하지 않는 것을 선호합니다. 두 개의 다른 클래스가 전역 변수를 공유해야하는 코드가있는 경우 솔루션을 리팩터링하고 클래스를 독립적으로 만들어야합니다.
나는 글로벌이 사용되어서는 안된다고 믿지 않습니다. 그러나 그들이 사용된다면 저자는 더 깨끗하고 거의 버그가없는 코드를 위해 몇 가지 원칙 (위에서 언급 한 것들과 다른 소프트웨어 엔지니어링 원칙과 모범 사례)을 고려해야합니다.
그것들은 필수적이며 화면이 좋은 예입니다. 그러나 다중 스레드 환경에서 또는 많은 개발자가 참여하는 경우 실제로 질문이 자주 발생합니다. 누가 (비정상적으로) 설정하거나 지웠습니까? 아키텍처에 따라 분석 비용이 많이 들고 자주 필요할 수 있습니다. 전역 var를 읽는 것은 괜찮을 수 있지만, 쓰기는 예를 들어 단일 스레드 또는 threadsafe 클래스에 의해 제어되어야합니다. 따라서 글로벌 변수는 자신이 악하다고 간주되는 결과로 인해 가능한 높은 개발 비용에 대한 두려움을 일으 킵니다. 따라서 일반적으로 전역 변수 수를 낮게 유지하는 것이 좋습니다.
eval
,import *
, 문자열 연결 , 변수id
, 속성 그림자 )