7. 단순문(Simple statements)¶
단순문은 하나의 논리적인 줄 안에 구성된다. 여러 개의 단순문이 세미콜론으로 분리되어 하나의 줄에 나올 수 있다. 단순문의 문법은 이렇다:
simple_stmt ::=expression_stmt
|assert_stmt
|assignment_stmt
|augmented_assignment_stmt
|annotated_assignment_stmt
|pass_stmt
|del_stmt
|return_stmt
|yield_stmt
|raise_stmt
|break_stmt
|continue_stmt
|import_stmt
|future_stmt
|global_stmt
|nonlocal_stmt
7.1. 표현식 문¶
표현식 문은 값을 계산하고 출력하거나, (보통) 프로시저(procedure) (의미 없는 결과를 돌려주는 함수; 파이썬에서 프로시저는 None
값을 돌려준다)를 호출하기 위해 (대부분 대화형으로) 사용된다. 표현식 문의 다른 사용도 허락되고 때때로 쓸모가 있다.
expression_stmt ::= starred_expression
표현식 문은 (하나의 표현식일 수 있는) 표현식 목록의 값을 구한다.
대화형 모드에서, 값이 None
이 아니면, 내장 repr()
함수를 사용해 문자열로 변환되고, 그렇게 나온 문자열을 별도의 줄에 표준 출력으로 보낸다 (결과가 None
일 때는 그렇지 않아서, 프로시저 호출은 어떤 출력도 만들지 않는다.),
7.2. 대입문¶
대입문은 이름을 값에 (재)연결하고 가변 객체의 어트리뷰트나 항목들을 수정한다.
assignment_stmt ::= (target_list
"=")+ (starred_expression
|yield_expression
) target_list ::=target
(","target
)* [","] target ::=identifier
| "(" [target_list
] ")" | "[" [target_list
] "]" |attributeref
|subscription
|slicing
| "*"target
(attributeref, subscription, slicing 의 문법 정의는 프라이머리 섹션을 보면 된다.)
대입문은 표현식 목록 (이것이 하나의 표현식일 수도, 쉼표로 분리된 목록일 수도 있는데, 후자의 경우는 튜플이 만들어진다는 것을 기억하라) 의 값을 구하고, 왼쪽에서 오른쪽으로, 하나의 결과 객체를 타깃 목록의 각각에 대입한다.
대입은 타깃 (목록)의 형태에 따라 재귀적으로 정의된다. 타깃이 가변 객체의 일부 (어트리뷰트 참조나 서브스크립션이나 슬라이싱) 면, 가변 객체가 최종적으로 대입을 수행해야만 하고, 그것이 올바른지 아닌지를 결정하고, 대입이 받아들여질 수 없으면 예외를 일으킬 수 있다. 다양한 형들이 주시하는 규칙들과 발생하는 예외들은 그 객체 형의 정의에서 주어진다 (표준형 계층 섹션을 보라).
객체를 타깃 목록, 괄호나 꺾쇠괄호로 둘러싸일 수 있는데 생략할 수 있다, 에 대입하는 것은 다음과 같이 재귀적으로 정의된다.
If the target list is a single target with no trailing comma, optionally in parentheses, the object is assigned to that target.
그렇지 않으면: 객체는 타깃 목록에 나오는 타깃의 수와 같은 수의 항목들을 제공하는 이터러블이어야 하고, 항목들은, 왼쪽에서 오른쪽으로, 대응하는 타깃들에 대입된다.
타깃 목록이 애스터리스크(asterisk)를 앞에 붙인 타깃, 《스타드(starred)》 타깃이라고 불린다, 하나를 포함하면: 객체는 적어도 타깃 목록에 나오는 타깃의 수보다 하나 작은 개수의 항목을 제공하는 이터러블이어야 한다. 이터러블의 처음 항목들은, 왼쪽에서 오른쪽으로, 스타드 타깃 앞에 나오는 타깃들에 대입된다. 이터러블의 마지막 항목들은 스타드 타깃 뒤에 나오는 타깃들에 대입된다. 이터러블의 나머지 항목들로 구성된 리스트가 스타드 타깃에 대입된다 (이 리스트는 이어있을 수 있다).
그렇지 않으면: 객체는 타깃 목록에 나오는 타깃의 수와 같은 수의 항목들을 제공하는 이터러블이어야 하고, 항목들은, 왼쪽에서 오른쪽으로, 대응하는 타깃들에 대입된다.
하나의 타깃에 대한 객체의 대입은 다음과 같이 재귀적으로 정의된다.
타깃이 식별자 (이름) 면:
그 이름이 현재 코드 블록에 있는
global
나nonlocal
문에 등장하지 않으면: 그 이름은 현재 지역 이름 공간에서 객체에 연결된다.그렇지 않으면: 그 이름은 각각 전역 이름 공간이나
nonlocal
에 의해 결정되는 외부 이름 공간에서 객체에 연결된다.
그 이름이 이미 연결되어 있으면 재연결된다. 이것은 기존에 연결되어 있던 객체의 참조 횟수가 0이 되도록 만들어서, 객체가 점유하던 메모리가 반납되고 파괴자(destructor) (갖고 있다면) 가 호출되도록 만들 수 있다.
타깃이 어트리뷰트 참조면: 참조의 프라이머리 표현식의 값을 구한다. 이것은 대입 가능한 어트리뷰트를 가진 객체를 주어야 하는데, 그렇지 않으면
TypeError
가 일어난다. 그에 그 객체에 주어진 어트리뷰트로 객체를 대입하도록 요청한다; 대입을 수행할 수 없다면 예외 (보통AttributeError
이지만, 꼭 그럴 필요는 없다) 를 일으킨다.주의 사항: 객체가 클래스 인스턴스이고 어트리뷰트 참조가 대입 연산자의 양쪽에서 모두 등장하면, RHS 표현식,
a.x
는 인스턴스 어트리뷰트나 (인스턴스 어트리뷰트가 없다면) 클래스 어트리뷰트를 액세스할 수 있다. LHS 타깃a.x
는 항상 필요하면 만들어서라도 항상 인스턴스 어트리뷰트를 설정한다. 그래서, 두a.x
가 같은 어트리뷰트를 가리키는 것은 필요조건이 아니다: RHS 표현식이 클래스 어트리뷰트를 가리킨다면, LHS 는 대입의 타깃으로 새 인스턴스 어트리뷰트를 만든다:class Cls: x = 3 # class variable inst = Cls() inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3
이 설명이
property()
로 만들어진 프로퍼티(property)와 같은 디스크립터 어트리뷰트에 적용될 필요는 없다.타깃이 서브스크립션이면: 참조에 있는 프라이머리 표현식의 값을 구한다. (리스트 같은) 가변 시퀀스 객체나 (딕셔너리 같은) 매핑 객체가 나와야 한다. 그런 다음, 서브 스크립트 표현식의 값을 구한다.
프라이머리가 (리스트 같은) 가변 시퀀스 객체면, 서브 스크립트는 정수가 나와야 한다. 음수면, 시퀀스의 길이가 더해진다. 결괏값은 시퀀스의 길이보다 작은 음이 아닌 정수여야 하고, 시퀀스에 그 인덱스를 가진 항목에 객체를 대입하라고 요청한다. 인덱스가 범위를 벗어나면,
IndexError
를 일으킨다 (서브 스크립트 된 시퀀스에 대한 대입은 리스트에 새 항목을 추가할 수 없다).프라이머리가 (딕셔너리 같은) 매핑 객체면, 서브 스크립트는 매핑의 키 형과 호환되는 형이어야 하고, 매핑에 그 서브 스크립트를 객체에 매핑하는 키/데이터 쌍을 만들도록 요청한다. 이때 같은 킷값을 갖는 기존의 키/값 쌍을 대체할 수도 있고, (같은 값의 키가 존재하지 않는 경우) 새 키/값 쌍을 삽입할 수도 있다.
사용자 정의 객체의 경우는, 적절한 인자로
__setitem__()
메서드가 호출된다.타깃이 슬라이싱이면: 참조의 프라이머리 표현식의 값을 구한다. (리스트 같은) 가변 시퀀스 객체가 나와야 한다. 대입되는 객체는 같은 형의 시퀀스 객체야 한다. 그런 다음, 존재한다면 하한과 상한 표현식의 값을 구한다; 기본값은 0과 시퀀스의 길이다. 경곗값은 정수가 되어야 한다. 둘 중 어느 것이건 음수가 나오면, 시퀀스의 길이를 더한다. 그렇게 얻어진 경곗값들을 0과 시퀀스의 길이나 그 사이에 들어가는 값이 되도록 자른다. 마지막으로 시퀀스 객체에 슬라이스를 대입되는 시퀀스로 변경하도록 요청한다. 타깃 시퀀스가 허락한다면, 슬라이스의 길이는 대입되는 시퀀스의 길이와 다를 수 있다.
CPython implementation detail: 현재 구현에서, 타깃의 문법은 표현식과 같게 유지되고, 잘못된 문법은 코드 생성 단계에서 거부되기 때문에 에러 메시지가 덜 상세해지는 결과를 낳고 있다.
설사 대입의 정의가 좌변과 우변 간의 중첩이 〈동시적(simultaneous)〉임을 (예를 들어, a, b = b, a
는 두 변수를 교환한다) 암시해도, 대입되는 변수들의 컬렉션 안 에서의 중첩은 왼쪽에서 오른쪽으로 일어나서, 때로 혼동할 수 있는 결과를 낳는다. 예를 들어, 다음과 같은 프로그램은 [0, 2]
를 인쇄한다:
x = [0, 1]
i = 0
i, x[i] = 1, 2 # i is updated, then x[i] is updated
print(x)
더 보기
- PEP 3132 - 확장 이터러블 언 패킹
*target
기능에 대한 규격
7.2.1. 증분 대입문(Augmented assignment statements)¶
증분 대입문은 한 문장에서 이항 연산과 대입문을 합치는 것이다:
augmented_assignment_stmt ::=augtarget
augop
(expression_list
|yield_expression
) augtarget ::=identifier
|attributeref
|subscription
|slicing
augop ::= "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**=" | ">>=" | "<<=" | "&=" | "^=" | "|="
(마지막 세 기호의 문법 정의는 프라이머리 섹션을 보면 된다.)
증분 대입은 타깃 (일반 대입문과는 달리 언 패킹이 될 수 없다) 과 표현식 목록의 값을 구하고, 둘을 피연산자로 삼아 대입의 형에 맞는 이항 연산을 수행한 후, 원래의 타깃에 그 결과를 대입한다. 타깃은 오직 한 번만 값이 구해진다.
x += 1
과 같은 증분 대입 표현은 x = x + 1
처럼 다시 쓸 수 있는데, 정확히 같은 효과는 아니지만 비슷한 결과를 준다. 증분 버전에서는, x
의 값을 오직 한 번만 구한다. 또한, 가능할 때, 실제 연산은 제자리(in-place) 에서 수행되는데, 새 객체를 만들고 그것을 타깃에 대입하기보다는, 예전 객체를 수정한다는 의미다.
일반 대입과는 달리, 증분 대입은 우변의 값을 구하기 이전에 좌변의 값을 구한다. 예를 들어, a[i] += f(x)
는 처음에 a[i]
를 조회한 다음, f(x)
의 값을 구하고, 덧셈을 수행하고, 마지막으로 그 결과를 a[i]
에 다시 쓴다.
하나의 문장에서 튜플과 다중 타깃으로 대입하는 것을 예외로 하면, 증분 대입문에 의한 대입은 일반 대입과 같은 방법으로 처리된다. 마찬가지로, 제자리 동작의 가능성을 예외로 하면, 증분 대입 때문에 수행되는 이진 연산은 일반 이진 연산과 같다.
어트리뷰트 참조인 타깃의 경우, 일반 대입처럼 클래스와 인스턴스 어트리뷰트에 관한 경고 가 적용된다.
7.2.2. 어노테이트된 대입문(Annotated assignment statements)¶
어노테이션 대입은, 한 문장에서, 변수나 어트리뷰트 어노테이션과 생략할 수 있는 대입문을 합치는 것이다.
annotated_assignment_stmt ::=augtarget
":"expression
["="expression
]
일반 대입문 과의 차이점은 오직 하나의 타깃과 오직 하나의 우변 값만 허락된다는 것이다.
대인 타깃에 단순한 이름을 쓰는 경우, 클래스나 모듈 스코프에 있으면, 어노테이션은 값이 구해진 후 특별한 클래스나 모듈의 어트리뷰트 __annotations__
에 저장되는데, 이 어트리뷰트는 (만약 비공개면 뒤섞인) 변수 이름을 어노테이션의 값으로 대응시키는 딕셔너리 매핑이다. 이 어트리뷰트는 쓰기가 허락되고, 클래스나 모듈의 실행을 시작할 때 어노테이션이 정적으로 발견되면 만들어진다.
대입 타깃으로 표현식을 쓸 때, 어노테이션은 클래스나 모듈 스코프에 있는 것처럼 값이 구해지지만 저장되지는 않는다.
이름이 함수 스코프에서 어노테이트되면, 이 이름은 그 스코프에 지역적(local)이다. 함수 스코프에서 어노테이션은 값이 구해지거나 저장되지 않는다.
우변이 존재하면, 어노테이트된 대입은 (적절한 곳에서) 어노테이션의 값을 구하기 전에 실제 대입을 수행한다. 표현식 타깃의 경우 우변이 존재하지 않으면, 인터프리터는 티깃의 값을 구하는데, 마지막 __setitem__()
이나 __setattr__()
호출은 생략한다.
더 보기
- PEP 526 - Syntax for Variable Annotations
The proposal that added syntax for annotating the types of variables (including class variables and instance variables), instead of expressing them through comments.
- PEP 484 - Type hints
The proposal that added the
typing
module to provide a standard syntax for type annotations that can be used in static analysis tools and IDEs.
7.3. assert
문¶
assert 문은 프로그램에 디버깅 어서션(debugging assertion)을 삽입하는 편리한 방법이다:
assert_stmt ::= "assert"expression
[","expression
]
간단한 형태, assert expression
은 다음과 동등하다
if __debug__:
if not expression: raise AssertionError
확장된 형태, assert expression1, expression2
는 다음과 동등하다
if __debug__:
if not expression1: raise AssertionError(expression2)
These equivalences assume that __debug__
and AssertionError
refer to
the built-in variables with those names. In the current implementation, the
built-in variable __debug__
is True
under normal circumstances,
False
when optimization is requested (command line option -O
). The current
code generator emits no code for an assert statement when optimization is
requested at compile time. Note that it is unnecessary to include the source
code for the expression that failed in the error message; it will be displayed
as part of the stack trace.
__debug__
에 대한 대입은 허락되지 않는다. 이 내장 변수의 값은 인터프리터가 시작할 때 결정된다.
7.4. pass
문¶
pass_stmt ::= "pass"
pass
는 널(null) 연산이다 — 실행될 때, 아무런 일도 일어나지 않는다. 문법적으로 문장이 필요하기는 하지만 할 일은 없을 때, 자리를 채우는 용도로 쓸모가 있다, 예를 들어:
def f(arg): pass # a function that does nothing (yet)
class C: pass # a class with no methods (yet)
7.5. del
문¶
del_stmt ::= "del" target_list
삭제는 대입이 정의된 방식과 아주 비슷하게 재귀적으로 정의된다. 전체 세부 사항들을 나열하는 대신, 여기 몇 가지 힌트가 있다.
타깃 목록의 삭제는 각 타깃을 왼쪽에서 오른쪽으로 재귀적으로 삭제한다.
이름의 삭제는 같은 코드 블록에 있는 global
문에 그 이름이 등장하는지에 따라 지역이나 전역 이름 공간에서 이름의 연결을 제거한다. 이름이 연결되어 있지 않으면, NameError
예외가 일어난다.
어트리뷰트 참조, 서브스크립션, 슬라이싱의 삭제는 관련된 프라이머리 객체로 전달된다; 슬라이싱의 삭제는 일반적으로 우변 형의 빈 슬라이스를 대입하는 것과 동등하다 (하지만 이것조차 슬라이싱 되는 객체가 판단한다).
버전 3.2에서 변경: 예전에는 이름이 중첩된 블록에서 자유 변수로 등장하는 경우 지역 이름 공간에서 삭제하는 것이 허락되지 않았다.
7.6. return 문¶
return_stmt ::= "return" [expression_list
]
return
은 문법적으로 클래스 정의에 중첩된 경우가 아니라, 함수 정의에만 중첩되어 나타날 수 있다.
표현식 목록이 있으면 값을 구하고, 그렇지 않으면 None
으로 치환된다.
return
은 표현식 목록 (또는 None
)을 반환 값으로 해서, 현재의 함수 호출을 떠난다.
return
이 finally
절을 가진 try
문에서 제어가 벗어나도록 만드는 경우, 함수로부터 진짜로 벗어나기 전에 그 finally
절이 실행된다.
제너레이터 함수에서, return
문은 제너레이터가 끝났음을 가리키고, StopIteration
예외를 일으킨다. return 문에 제공되는 값은 (있다면) StopIteration
의 생성자에 인자로 전달되어 StopIteration.value
어트리뷰트가 된다.
비동기 제너레이터 함수에서, 빈 return
문은 비동기 제너레이터가 끝났음을 알리고, StopAsyncIteration
예외를 일으킨다. 비동기 제너레이터 함수에서, 비어있지 않은 return
은 문법 에러다.
7.7. yield 문¶
yield_stmt ::= yield_expression
yield
문은 yield 표현식 과 같은 의미가 있다. 동등한 yield 표현식에서 필요로 하는 괄호를 생략하기 위해 yield 문을 사용한다. 예를 들어, yield 문
yield <expr>
yield from <expr>
은 다음과 같은 yield 표현식 문장들과 동등하다
(yield <expr>)
(yield from <expr>)
yield 표현식과 문장은 제너레이터 함수를 정의할 때만 사용되고, 제너레이터 함수의 바디에서만 사용된다. 함수 정의가 일반 함수 대신 제너레이터 함수를 만들도록 하는 데는 yield를 사용하는 것만으로 충분하다.
yield
의 뜻에 대한 전체 세부 사항들은 일드 표현식(Yield expressions) 섹션을 참고하면 된다.
7.8. raise
문¶
raise_stmt ::= "raise" [expression
["from"expression
]]
표현식이 주어지지 않으면, raise
는 현재 스코프에서 활성화된 마지막 예외를 다시 일으킨다. 현재 스코프에 활성화된 예외가 없다면, 이것이 에러라는 것을 알리기 위해 RuntimeError
예외를 일으킨다.
그렇지 않으면, raise
는 예외 객체로, 첫 번째 표현식의 값을 구한다. BaseException
의 서브 클래스나 인스턴스여야 한다. 클래스면, 예외 인스턴스는 필요할 때 인자 없이 클래스의 인스턴스를 만들어서 사용된다.
예외의 형(type)은 예외 인스턴스의 클래스고, 값(value)은 인스턴스 자신이다.
트레이스백 객체는 보통 예외가 일어날 때 자동으로 만들어지고 쓰기 가능한 __traceback__
어트리뷰트로 첨부된다. 다음과 같이, with_traceback()
예외 메서드를 사용하면, 예외를 만들고 트레이스백을 직접 설정하는 것을 한 번에 할 수 있다 (같은 예외 인스턴스를 돌려주는데, 그 인자값으로 트레이스백을 설정해준다):
raise Exception("foo occurred").with_traceback(tracebackobj)
from
절은 예외 연쇄(exception chaining)에 사용된다. 주어진다면, 두 번째 표현식(expression) 은 또 하나의 예외 클래스나 인스턴스야 되는데, 발생한 예외에 (쓰기 가능한) __cause__
어트리뷰트로 첨부된다. 발생한 예외가 처리되지 않으면, 두 예외가 모두 인쇄된다:
>>> try:
... print(1 / 0)
... except Exception as exc:
... raise RuntimeError("Something bad happened") from exc
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened
예외 처리기나 finally
절에서 예외가 발생하면 비슷한 메커니즘이 묵시적으로 적용된다: 앞선 예외가 새 예외의 __context__
어트리뷰트로 첨부된다.
>>> try:
... print(1 / 0)
... except:
... raise RuntimeError("Something bad happened")
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened
예외 연쇄는 from
절에 None
을 지정해서 명시적으로 중지시킬 수 있다:
>>> try:
... print(1 / 0)
... except:
... raise RuntimeError("Something bad happened") from None
...
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened
예외에 대한 더 많은 정보를 예외 섹션에서 발견할 수 있고, 예외를 처리하는 것에 대한 정보는 try 문 섹션에 있다.
버전 3.3에서 변경: 이제 raise X from Y
에서 Y
로 None
이 허락된다.
버전 3.3에 추가: 예외 문백(exception context)의 자동 출력을 제한할 수 있는 __suppress_context__
어트리뷰트
7.9. break 문¶
break_stmt ::= "break"
break
는 문법적으로 for
나 while
루프에 중첩되어서만 나타날 수 있다. 하지만 그 루프 안의 함수나 클래스 정의에 중첩되지는 않는다.
가장 가까이서 둘러싸고 있는 루프를 종료하고, 그 루프가 else
절을 갖고 있다면 건너뛴다(skip).
for
루프가 break
로 종료되면, 루프 제어 타깃은 현재값을 유지한다.
break
가 finally
절을 가 try
문에서 제어가 벗어나도록 만드는 경우, 루프로부터 진짜로 벗어나기 전에 그 finally
절이 실행된다.
7.10. continue
문¶
continue_stmt ::= "continue"
continue
는 문법적으로 for
나 while
루프에 중첩되어서만 나타날 수 있다. 하지만 그 루프 안의 함수나 클래스 정의 또는 그 루프 내의 finally
에 중첩되지는 않는다. 가장 가까이서 둘러싸고 있는 루프가 다음 사이클로 넘어가도록 만든다.
continue
가 finally
절을 가진 try
문에서 제어가 벗어나도록 만드는 경우, 다음 루트 사이클을 시작하기 전에 그 finally
절이 실행된다.
7.11. 임포트(import
) 문¶
import_stmt ::= "import"module
["as"identifier
] (","module
["as"identifier
])* | "from"relative_module
"import"identifier
["as"identifier
] (","identifier
["as"identifier
])* | "from"relative_module
"import" "("identifier
["as"identifier
] (","identifier
["as"identifier
])* [","] ")" | "from"module
"import" "*" module ::= (identifier
".")*identifier
relative_module ::= "."*module
| "."+
(from
절이 없는) 기본 임포트 문은 두 단계로 실행된다:
모듈을 찾고, 로드하고, 필요하면 초기화한다
임포트(
import
) 문이 등장한 스코프의 지역 이름 공간에 이름이나 이름들을 정의한다.
문장이 (쉼표로 분리된) 여러 개의 절을 포함하면, 마치 각 절이 별도의 임포트 문에 의해 분리된 것처럼, 두 단계는 절마다 별도로 수행된다.
첫 번째 단계, 모듈을 찾고 로드하는 것의 세부 사항은 임포트 시스템 에 있는 섹션에서 아주 상세하게 설명하는데, 임포트될 수 있는 여러 종류의 패키지와 모듈들과 임포트 시스템을 커스터마이즈하는데 사용될 수 있는 모든 훅에 관해서도 설명하고 있다.
요청된 모듈이 성공적으로 읽어 들여지면, 세 가지 중 한 방법으로 지역 이름 공간에 소개된다:
다른 이름이 지정되지 않고, 임포트되는 모듈이 최상위 모듈이면, 모듈의 이름이 임포트되는 모듈에 대한 참조로 지역 이름 공간에 연결된다.
임포트되는 모듈이 최상이 모듈이 아니 라면, 그 모듈을 포함하는 최상위 패키지의 이름이 최상위 패키지에 대한 참조로 지역 이름 공간에 연결된다. 임포트된 모듈은 직접적이기보다는 완전히 정규화된 이름(full qualified name)을 통해 액세스 되어야 한다.
from
형은 약간 더 복잡한 절차를 사용한다:
from
절에 지정된 모듈을 찾고, 로드하고, 필요하면 초기화한다import
절에 지정된 식별자들 각각에 대해:임포트된 모듈이 그 이름의 어트리뷰트를 가졌는지 검사한다
없으면, 그 이름의 서브 모듈을 임포트하는 것을 시도한 다음 임포트된 모듈에서 그 어트리뷰트를 다시 검사한다
어트리뷰트가 발견되지 않으면
ImportError
를 일으킨다.그렇지 않으면, 그 값에 대한 참조가 지역 이름 공간에 저장되는데,
as
절이 존재하면 거기에서 지정된 이름을 사용하고, 그렇지 않으면 어트리뷰트 이름을 사용한다
사용 예:
import foo # foo imported and bound locally
import foo.bar.baz # foo.bar.baz imported, foo bound locally
import foo.bar.baz as fbb # foo.bar.baz imported and bound as fbb
from foo.bar import baz # foo.bar.baz imported and bound as baz
from foo import attr # foo imported and foo.attr bound as attr
식별자들의 목록을 스타 ('*'
) 로 바꾸면, 모듈에 정의된 모든 공개 이름들이 import
문이 등장한 스코프의 지역 이름 공간에 연결된다.
모듈에 정의된 공개 이름(public names) 은 모듈의 이름 공간에서 __all__
이라는 이름의 변수를 검사해서 결정된다; 정의되어 있다면, 문자열의 시퀀스여야 하는데, 그 모듈이 정의하거나 임포트하는 이름들이다. __all__
에서 지정한 이름들은 모두 공개로 취급되고 반드시 존재해야 한다. __all__
이 정의되지 않으면, 모듈의 이름 공간에서 발견되는 이름 중, 밑줄 문자 ('_'
)로 시작하지 않는 모든 이름이 공개로 취급된다. __all__
는 공개 API 전체를 포함해야 한다. 이것의 목적은 의도치 않게 API 일부가 아닌 항목들을 노출하는 것을 방지하는 것이다 (가령 그 모듈이 임포트하고 사용하는 라이브러리 모듈).
임포트의 와일드카드 형태 — from module import *
— 는 모듈 수준에서만 허락된다. 클래스나 함수 정의에서 사용하려는 시도는 SyntaxError
를 일으킨다.
임포트할 모듈을 지정할 때 모듈의 절대 이름(absolute name)을 지정할 필요는 없다. 모듈이나 패키지가 다른 패키지 안에 포함될 때, 같은 상위 패키지 내에서는 그 패키지 이름을 언급할 필요 없이 상대 임포트(relative import)를 할 수 있다. from
뒤에 지정되는 패키지나 모듈 앞에 붙이는 점으로, 정확한 이름을 지정하지 않고도 현재 패키지 계층을 얼마나 거슬러 올라가야 하는지 지정할 수 있다. 하나의 점은 이 임포트를 하는 모듈이 존재하는 현재 패키지를 뜻한다. 두 개의 점은 한 패키지 수준을 거슬러 올라가는 것을 뜻한다. 세 개의 점은 두 개의 수준을, 등등이다. 그래서 pkg
패키지에 있는 모듈에서 from . import mod
를 실행하면, pkg.mod
를 임포트하게 된다. pkg.subpkg1
안에서 from ..subpkg2 import mod
를 실행하면 pkg.subpkg2.mod
를 임포트하게 된다. 상대 임포트에 대한 규격은 PEP 328 안에 들어있다.
로드할 모듈들을 동적으로 결정하는 응용 프로그램들을 지원하기 위해 importlib.import_module()
이 제공된다.
7.11.1. 퓨처 문¶
퓨처 문(future statement)은 컴파일러가 특정한 모듈을 특별한 문법이나 개념을 사용해서 컴파일하도록 만드는 지시어(directive)인데, 그 기능은 미래에 출시되는 파이썬에서 표준이 되는 것이다.
퓨처 문의 목적은 언어에 호환되지 않는 변경이 도입된 미래 버전의 파이썬으로 옮겨가는 것을 쉽게 만드는 것이다. 그 기능이 표준이 되는 배포 이전에 모듈 단위로 새 기능을 사용할 수 있도록 만든다.
future_stmt ::= "from" "__future__" "import"feature
["as"identifier
] (","feature
["as"identifier
])* | "from" "__future__" "import" "("feature
["as"identifier
] (","feature
["as"identifier
])* [","] ")" feature ::=identifier
퓨처 문은 모듈의 거의 처음에 나와야 한다. 퓨처 문 앞에 나올 수 있는 줄들은:
모듈 독스트링(docstring) (있다면),
주석
빈 줄, 그리고
다른 퓨처 문들
파이썬 3.0 이 인식하는 기능들은 absolute_import
, division
, generators
, unicode_literals
, print_function
, nested_scopes
, with_statement
다. 이것들은 잉여물인데 항상 활성화되고, 오직 과거 호환성을 위해 유지되고 있기 때문이다.
퓨처 문은 구체적으로는 컴파일 시점에 인식되고 다뤄진다: 핵심 구성물들의 의미에 대한 변경은 종종 다른 코드 생성을 통해 구현된다. 새 기능이 호환되지 않는 (새로운 예약어처럼) 새로운 문법을 도입하는 경우조차 가능한데, 이 경우는 컴파일러가 모듈을 다르게 파싱할 수 있다. 그런 결정들은 실행 시점으로 미뤄질 수 없다..
배포마다, 컴파일러는 어떤 기능 이름들이 정의되어 있는지 알고, 만약 퓨처 문이 알지 못하는 기능을 포함하고 있으면 컴파일 시점 에러를 일으킨다.
직접적인 실행 시점의 개념은 다른 임포트 문들과 같다: 표준 모듈 __future__
, 후에 설명한다, 다 있고, 퓨처 문이 실행되는 시점에 일반적인 방법으로 임포트된다.
흥미로운 실행 시점의 개념들은 퓨처 문에 의해 활성화되는 구체적인 기능들에 달려있다.
이런 문장에는 아무것도 특별한 것이 없음에 주의해야 한다:
import __future__ [as name]
이것은 퓨처 문이 아니다; 아무런 특별한 개념이나 문법적인 제약이 없는 평범한 임포트 문일 뿐이다.
퓨처 문을 포함하는 모듈 M
에 등장하는 내장 함수 exec()
와 compile()
를 호출해서 컴파일되는 코드는, 기본적으로는, 퓨처 문이 지정하는 새 문법과 개념을 사용한다. 이것은 compile()
에 주는 생략 가능한 인자로 제어될 수 있다 — 자세한 내용은 그 함수의 문서를 보면 된다.
대화형 인터프리터 프롬프트에서 입력된 퓨처 문은 인터프리터 세션의 남은 기간 효과를 발생시킨다. 인터프리터가 -i
, 실행할 스크립트 이름이 전달된다, 옵션으로 시작하고, 그 스크립트가 퓨처 문을 포함하면, 스크립트가 실행된 이후에 시작되는 대화형 세션에서도 효과를 유지한다.
더 보기
- PEP 236 - 백 투 더 __future__
__future__ 메커니즘에 대한 최초의 제안.
7.12. global
문¶
global_stmt ::= "global"identifier
(","identifier
)*
global
문은 현재 코드 블록 전체에 적용되는 선언이다. 나열된 식별자들이 전역으로 해석되어야 한다는 뜻이다. global 선언 없이 자유 변수들이 전역을 가리킬 수 있기는 하지만, global
없이 전역 변수에 값을 대입하는 것은 불가능하다.
global
문에 나열된 이름들은 같은 코드 블록에서 global
문 앞에 등장할 수 없다.
global
문에 나열된 이름들은 형식 파라미터나 for
루프 제어 타깃, 클래스(class
) 정의, 함수 정의, 임포트(import
) 문, 변수 어노테이션으로 정의되지 않아야 한다.
CPython implementation detail: 현재 구현이 이 제약들의 일부를 강제하지 않지만, 프로그램은 이 자유를 남용하지 말아야 하는데, 미래의 구현은 그것들을 강제하거나 프로그램의 의미를 예고 없이 변경할 수 있기 때문이다.
프로그래머의 주의 사향: global
은 파서에 주는 지시자(directive)다. global
문과 같은 시점에 파싱되는 코드에만 적용된다. 특히, 내장 exec()
함수로 공급되는 문자열이나 코드 객체에 포함된 global
문은 그 함수 호출을 포함하는 코드 블록에는 영향을 주지 않고, 그런 문자열에 포함된 코드 역시 함수 호출을 포함하는 코드에 있는 global
문에 영향을 받지 않는다. eval()
과 compile()
함수들도 마찬가지다.
7.13. nonlocal
문¶
nonlocal_stmt ::= "nonlocal"identifier
(","identifier
)*
nonlocal
문은 나열된 식별자들이 전역을 제외하고 가장 가까이서 둘러싸는 스코프에서 이미 연결된 변수를 가리키도록 만든다. 이것은 중요한데, 연결의 기본 동작이 지역 이름 공간을 먼저 검색하는 것이기 때문이다. 이 문장은 캡슐화된 코드가 전역 (모듈) 스코프 외에 지역 스코프 밖의 변수들에 재연결할 수 있도록 한다.
nonlocal
문 에 나열된 이름들은, global
문에 나열된 것들과는 달리, 둘러싼 스코프에서 이미 존재하는 연결들을 가리켜야만 한다 (새 연결이 어떤 스코프에 만들어져야만 하는지 명확하게 결정할 수 없다).
nonlocal
문에 나열되는 이름들은 지역 스코프에 이미 존재하는 연결들과 겹치지 않아야 한다.