with 사용 - 컨텍스트 내에 어떤 변수가 있는지 확인하는 방법
문제
~ 안에 이 Kivy 코드:
class MyPaintWidget(Widget):
def on_touch_down(self, touch):
userdata = touch.ud
with self.canvas:
Color(1, 1, 0)
d = 30.
Ellipse(pos=(touch.x - d/2, touch.y - d/2), size=(d, d))
userdata['line'] = Line(points=(touch.x, touch.y))
보기에 Color
그리고 d
그리고 Ellipse
다음의 네임스페이스 내에 있습니다. self.canvas
, 그러나 Python은 그것을 어떻게 알 수 있습니까? userdata
동일한 네임스페이스 내에 있지 않습니까?
해결책
편집 :이 대답은 조금 길어졌습니다. 그래서 요약이 있습니다.
-
with self.canvas
다음 코드 블록에 대해 현재 활성 캔버스 을 정의합니다. -
Color
또는Ellipse
와 같은 모든 도면 지침은 활성 캔버스에 끌어냅니다.
네임 스페이스는 실제로 무엇이든 할 수 없습니다. 그것은 중요한 것입니다 (아래 참조).
with
문을 사용하면 컨텍스트 관리자 .
구문은 다음과 같습니다
with thing [as foo]:
.
여기서 thing
는 일반적으로 contextlib.contextmanager
decogerator로 장식 된 함수입니다. Context Manager가 정확히 무엇이 구현되는지에 따라 다릅니다.
그러나 수행하지 않는 것이 변수가 당신의 범위에 마술처럼 나타납니다. 컨텍스트에 대한 참조는 선택적 thing
절에 의해 얻어 질 수 있지만 그게 다를 수 있습니다. 예제의 as foo
및 Color
는 다른 곳에서오고 있습니다 (아마도 가져 오기?).
Ellipse
라인에서 Context Manager가 정확히 수행하는 것을 알아 보려면 API 문서 또는 소스 코드 with self.canvas
.
여기에서 자습서에서 관련 발췌문 :
with with 문을 사용하여 모든 연속적인 그림 명령 적절하게 들여 쓰기는이 캔버스를 수정합니다. with 문장 또한 도면 이후에 내부 상태를 청소할 수 있습니다. 올바르게 올라간다.
kivy.graphics.instructions.Canvas
및 Color
는 Ellipse
에 영향을 미치지 만 With 문장에서 어떤 방식 으로든 정의되지는 않습니다.
소스 코드를보고 이것은 작동 방식입니다.
def class CanvasBase(InstructionGroup):
def __enter__(self):
pushActiveCanvas(self)
def __exit__(self, *largs):
popActiveCanvas()
.
self.canvas
및 __enter__
컨텍스트 관리자가 입력 된 경우 (__exit__
문 후에 들여 쓰기 된 코드의 첫 번째 줄 앞에) 일어나는 경우 일어나는 일을 정의하십시오.
이 경우 캔버스는 현재 활성 캔버스를 정의하는 스택 을 정의하는 스택 (및 컨텍스트 관리자가 종료 된 경우 팝업)을 사용합니다.
with
에서 모든 도면 지침에 대한 명백한 기본 클래스 인 부모는 현재 활성화 된 캔버스로 설정됩니다 :
self.parent = getActiveCanvas()
.다른 팁
실제로, Color
그리고 Ellipse
에서 수입됩니다 kivy.graphics
코드에서 조금 더 높게:
from kivy.graphics import Color, Ellipse
네임스페이스에 대한 질문에 대답하기 위해 Python은 변수를 가져오는 네임스페이스가 무엇인지 "알" 필요가 전혀 없습니다.함수, 객체, 클래스, 전역 및 패키지 범위를 차례로 검색하는 Java와 같은 언어에 비해 매우 간단한 네임스페이스 규칙을 가지고 있습니다.Python에는 모듈당 하나의 전역 네임스페이스와 로컬 네임스페이스 스택(예:중첩된 함수는 외부 함수의 변수를 가져올 수 있습니다.문제의 변수 이름을 찾을 때까지 범위 목록을 따라갑니다.
그만큼 with
위의 진술은 특별한 의미가 있지만 내 생각에는 with
암시적으로 새 변수를 로컬 범위에 도입할 수 없습니다. as
조항).