programing

Python에서 범위 차단

itmemos 2023. 7. 31. 21:06
반응형

Python에서 범위 차단

다른 언어로 코딩할 때 다음과 같은 블록 범위를 만들기도 합니다.

statement
...
statement
{
    statement
    ...
    statement
}
statement
...
statement

(많은) 목적 중 하나는 코드 가독성을 향상시키는 것입니다. 즉, 특정 문이 논리 단위를 형성하거나 특정 로컬 변수가 해당 블록에서만 사용된다는 것을 보여주는 것입니다.

파이썬에서 같은 것을 하는 관용적인 방법이 있습니까?

아니요, 블록 범위를 만드는 데는 언어 지원이 없습니다.

다음 구성은 범위를 만듭니다.

  • 모듈
  • 학급
  • 함수( 람다 제외)
  • 생성자 표현식
  • 이해 관계(Dict, set, list(Python 3.x))

파이썬의 관용적인 방법은 기능을 짧게 유지하는 것입니다.만약 당신이 이것이 필요하다고 생각한다면, 당신의 코드를 리팩터링하세요! :)

Python은 각 모듈, 클래스, 함수, 제너레이터 표현식, 딕트 이해, 세트 이해 및 Python 3.x에서도 각 목록 이해에 대한 새로운 범위를 만듭니다.이 외에도 함수 내부에는 중첩된 범위가 없습니다.

함수 내부에 함수를 선언한 다음 즉시 호출하여 Python의 C++ 블록 범위와 유사한 작업을 수행할 수 있습니다.예:

def my_func():
    shared_variable = calculate_thing()

    def do_first_thing():
        ... = shared_variable
    do_first_thing()

    def do_second_thing():
        foo(shared_variable)
        ...
    do_second_thing()

왜 이 작업을 수행해야 하는지 잘 모르겠으면비디오를 통해 확신할 수 있습니다.

필요한 보다 더 유형하지 않고 을 가능한 한 조사하는 입니다. - 것도 이 '쓰레기'를 . 다른 어떤 것도 이 시스템을 사용하기를 원하지 않습니다.do_first_thing()예를 들어 호출 함수 밖으로 범위를 지정하면 안 됩니다.

저는 블록 범위가 없다는 것에 동의합니다.그러나 Python 3의 한 장소는 블록 스코프를 가진 것처럼 보이게 합니다.

무슨 일이 일어났길래 이런 표정을 지었습니까?

이것은 Python 2에서 제대로 작동했지만 Python 3에서 변수 유출을 멈추기 위해 그들은 이 속임수를 썼고 이 변화는 마치 여기에 블록 범위가 있는 것처럼 보이게 합니다.

제가 설명해 드릴게요.


범위 개념에 따라 동일한 범위 내에서 이름이 같은 변수를 도입할 때 그 값을 수정해야 합니다.

다음은 Python 2에서 일어나고 있는 일입니다.

>>> x = 'OLD'
>>> sample = [x for x in 'NEW']
>>> x
'W'

그런데 파이썬 3에서는 이름이 같은 변수를 도입해도 오버라이드가 되지 않고, 리스트 이해가 왠지 샌드박스처럼 작용하고, 그 안에서 새로운 스코프를 만드는 것 같습니다.

>>> x = 'OLD'
>>> sample = [x for x in 'NEW']
>>> x
'OLD'

그리고 이 대답은 대답자 토마스와 상반됩니다.H의 진술 스코프를 만드는 유일한 수단은 함수, 클래스 또는 모듈입니다. 왜냐하면 이것은 새로운 스코프를 만드는 다른 한 곳처럼 보이기 때문입니다.

저는 당신의 코드에 소개할 수 있는 가장 쉬운 인터페이스와 최소한의 추가 이름을 가진 해결책을 생각해냈습니다.

from scoping import scoping
a = 2
with scoping():
    assert(2 == a)
    a = 3
    b = 4
    scoping.keep('b')
    assert(3 == a)
assert(2 == a)
assert(4 == b)

https://pypi.org/project/scoping/

완전성을 위해:del을 사용하여 로컬 변수의 범위를 끝낼 수 있습니다.참고 항목: Python에서 유용한 경우?하지만 그것은 확실히 관용적이지 않습니다.

statement
statement

# Begin block
a = ...
b = ...
statement
statement
del a, b
# End block

statement

모듈(및 패키지)은 프로그램을 별도의 네임스페이스로 분할할 수 있는 훌륭한 파이썬 방식이며, 이는 이 질문의 암묵적인 목표인 것 같습니다.실제로 파이썬의 기초를 배우면서 블록 스코프 기능이 없어 답답함을 느꼈습니다.하지만 파이썬 모듈을 이해한 후에는 블록 범위 없이 이전 목표를 보다 우아하게 실현할 수 있었습니다.

동기 부여로서, 그리고 사람들을 올바른 방향으로 이끌기 위해, 저는 파이썬의 범위 지정 구조 중 일부에 대한 명시적인 예를 제공하는 것이 유용하다고 생각합니다.먼저 Python 클래스를 사용하여 블록 범위를 구현하려는 실패한 시도를 설명합니다.다음으로 Python 모듈을 사용하여 어떻게 더 유용한 것을 달성했는지 설명하겠습니다.마지막으로 데이터 로드 및 필터링에 패키지를 실용적으로 적용하는 방법을 개략적으로 설명합니다.

클래스가 있는 블록 범위 시도 중

잠시 동안 클래스 선언 안에 코드를 삽입하여 블록 범위를 달성했다고 생각했습니다.

x = 5
class BlockScopeAttempt:
    x = 10
    print(x) # Output: 10
print(x) # Output: 5

안타깝게도 함수가 정의되면 다음과 같이 분류됩니다.

x = 5 
class BlockScopeAttempt: 
    x = 10
    print(x) # Output: 10
    def printx2(): 
        print(x) 
    printx2() # Output: 5!!!

클래스 내에서 정의된 함수는 전역 범위를 사용하기 때문입니다.이 문제를 해결하는 가장 쉬운 방법은 클래스를 명시적으로 지정하는 것입니다.

x = 5 
class BlockScopeAttempt: 
    x = 10
    print(x) # Output: 10
    def printx2(): 
        print(BlockScopeAttempt.x)  # Added class name
    printx2() # Output: 10

클래스에 포함되어 있는지 여부에 따라 함수를 다르게 작성해야 하기 때문에 이것은 그렇게 우아하지 않습니다.

Python 모듈을 통해 더 나은 결과 제공

모듈은 정적 클래스와 매우 유사하지만 제 경험으로는 모듈이 훨씬 깨끗합니다.저는 모에서도마파만일듭다니라는 .my_module.py다음 내용을 포함하는 현재 작업 디렉터리:

x = 10
print(x) # (A)

def printx():
    print(x) # (B)

def alter_x():
    global x
    x = 8

def do_nothing():
    # Here x is local to the function.
    x = 9

그러면 나의 메인 파일이나 대화형(예: 주피터) 세션에서, 나는 합니다.

x = 5
from my_module import printx, do_nothing, alter_x  # Output: 10 from (A)
printx()  # Output: 10 from (B)
do_nothing()
printx()  # Output: 10
alter_x()
printx()  # Output: 8
print(x) # Output: 5
from my_module import x  # Copies current value from module
print(x) # Output: 8
x = 7
printx()  # Output: 8
import my_module
my_module.x = 6
printx()  # Output: 6

설명하자면, 각 Python 파일은 자체 글로벌 네임스페이스를 가진 모듈을 정의합니다.import my_module명령을 사용하여 이 네임스페이스의 변수에 액세스할 수 있습니다..통사론저는 정적인 수업 같은 모듈을 생각합니다.

대화형 세션에서 모듈로 작업하는 경우 처음에 이 두 줄을 실행할 수 있습니다.

%load_ext autoreload
%autoreload 2

모듈은 해당 파일이 수정될 때 자동으로 다시 로드됩니다.

데이터 로드 및 필터링용 패키지

패키지의 개념은 모듈 개념의 약간의 확장입니다.패키지는 다음을 포함하는 디렉토리입니다(공백일 수 있음).__init__.py가져올 때 실행되는 파일입니다.이 디렉토리 내의 모듈/패키지는 다음을 사용하여 액세스할 수 있습니다..통사론

데이터 분석을 위해 대용량 데이터 파일을 읽고 다양한 필터를 대화형으로 적용해야 하는 경우가 많습니다.파일을 읽는 데 몇 분이 걸리기 때문에 한 번만 읽고 싶습니다.저는 학교에서 객체 지향 프로그래밍에 대해 배운 것을 바탕으로 필터링과 로딩을 위한 코드를 수업의 방법으로 작성해야 한다고 믿었습니다.이 접근 방식의 주요 단점은 필터를 재정의하면 클래스의 정의가 변경되므로 데이터를 포함한 전체 클래스를 다시 로드해야 한다는 것입니다.

요즘 파이썬을 사용하여 다음과 같은 패키지를 정의합니다.my_data이름이 지정된 하위 모듈이 포함되어 있습니다.load그리고.filter내부filter.py상대적으로 가져올 수 있습니다.

from .load import raw_data

수정할 경우filter.py,그리고나서autoreload변경 사항을 탐지합니다.다시 로드되지 않습니다.load.py데이터를 다시 로드할 필요가 없습니다.이렇게 하면 필터링 코드를 주피터 노트북에 프로토타입으로 만들고 함수로 래핑한 다음 노트북에서 직접 잘라낼 수 있습니다.filter.py이 사실을 알게 된 것은 제 작업 흐름에 혁명을 일으켰고, 저를 회의주의자에서 "파이썬의 젠"의 신봉자로 변화시켰습니다.

언급URL : https://stackoverflow.com/questions/6167923/block-scope-in-python

반응형