내가 실수하지 않는 한, 파이썬에서 함수를 생성하면 다음과 같이 작동합니다.
def my_func(param1, param2):
# stuff
그러나 실제로 해당 매개 변수 유형을 제공하지는 않습니다. 또한 내가 기억한다면 파이썬은 강력한 유형의 언어이므로 파이썬이 함수 생성자가 예상 한 것과 다른 유형의 매개 변수를 전달해서는 안되는 것처럼 보입니다. 그러나 파이썬은 함수의 사용자가 올바른 유형으로 전달되고 있음을 어떻게 알 수 있습니까? 함수가 실제로 매개 변수를 사용한다고 가정하면 잘못된 유형의 경우 프로그램이 죽습니까? 유형을 지정해야합니까?
답변
파이썬은 모든 객체 가 타입을 가지고 있기 때문에 강력하게 타이핑됩니다. 모든 객체 는 타입을 알고 있습니다. 우연히 또는 고의적으로 다른 타입 의 객체 인 것처럼 “유사한”타입의 객체를 사용할 수 없으며 객체의 모든 기본 연산은 다음과 같습니다. 해당 유형으로 위임되었습니다.
이것은 이름 과 관련이 없습니다 . 이름 의 이름이 정의 때, 이름이 참조하는 경우와 : 파이썬에서 “는 유형이”하지 않는 개체 와 개체 유형을 가지고있다 (하지만 사실 힘에의 유형하지 않는 이름을 하십시오 이름은 이름입니다).
파이썬의 이름은 다른 시간에 다른 객체를 완벽하게 참조 할 수 있습니다 (모두는 아니지만 대부분의 프로그래밍 언어에서와 같이) .X 유형의 객체를 한 번 언급 한 경우 이름에 제한이 없습니다. 그런 다음 X 유형의 다른 객체 만 참조하도록 영원히 제한됩니다. 이름 에 대한 제약 조건 은 “강력한 타이핑”개념의 일부가 아니지만 정적 유형에 대한 애호가 (이름 이 제약을받는 정적 AKA 컴파일- 시간, 패션도) 이런 식으로 용어를 잘못 사용합니다.
답변
다른 답변은 오리 타이핑과 tzot의 간단한 답변 을 설명하는 데 훌륭한 역할을했습니다 .
파이썬에는 변수에 유형과 값이있는 다른 언어와 같이 변수가 없습니다. 유형을 알고있는 객체를 가리키는 이름이 있습니다.
그러나 2010 년 이후 (질문이 처음 제기 될 때) 한 가지 흥미로운 점, 즉 PEP 3107 (Python 3에서 구현 됨)이 변경되었습니다. 이제 실제로 다음과 같이 매개 변수의 유형과 함수의 리턴 유형을 지정할 수 있습니다.
def pick(l: list, index: int) -> int:
return l[index]
여기서 우리는 pick
리스트 l
와 정수의 2 개의 매개 변수 를 취하는 것을 볼 수 있습니다 index
. 또한 정수를 반환해야합니다.
따라서 여기에는 l
많은 노력없이 볼 수있는 정수 목록이 포함되어 있지만 더 복잡한 함수의 경우 목록에 포함 해야하는 내용에 대해 약간 혼란 스러울 수 있습니다. 또한 기본값 인 index
0을 원합니다.이를 해결하려면 다음 pick
과 같이 작성하십시오 .
def pick(l: "list of ints", index: int = 0) -> int:
return l[index]
l
구문 유형으로 허용되는 유형의 문자열을 문자열에 넣었 지만 프로그래밍 방식으로 구문 분석하는 것은 좋지 않습니다 (나중에 다시 올 것입니다).
파이썬은 인상하지 않을 것이 중요합니다 TypeError
당신이에 float를 전달하는 경우 index
: 그 이유는 파이썬의 디자인 철학의 주요 포인트 중 하나입니다 “우리는 모두 여기에 성인을 동의하고” 당신이 예상하는 수단 함수에 전달할 수있는 것과 할 수없는 것을 알고 있어야합니다. 실제로 TypeErrors를 발생시키는 코드를 작성하려면이 isinstance
함수를 사용 하여 전달 된 인수가 다음과 같이 올바른 유형 또는 서브 클래스인지 확인하십시오.
def pick(l: list, index: int = 0) -> int:
if not isinstance(l, list):
raise TypeError
return l[index]
왜 이런 일을 거의하지 말아야하는지에 대한 자세한 내용은 다음 섹션과 주석에서 설명합니다.
PEP 3107 은 코드 가독성을 향상시킬뿐만 아니라 여기에서 읽을 수있는 몇 가지 적합한 사용 사례도 있습니다 .
타입 주석에 대한 표준 모듈을 소개하는 PEP 484 가 도입 되면서 파이썬 3.5에서 타입 주석이 더 주목을 받았습니다 .
이 유형 힌트는 유형 검사기 mypy ( GitHub )에서 왔으며 현재 PEP 484를 준수합니다.
타이핑 모듈에는 다음을 포함하여 매우 포괄적 인 유형 힌트 모음이 제공됩니다.
List
,Tuple
,Set
,Map
-에list
,tuple
,set
및map
각각.Iterable
-발전기에 유용합니다.Any
-언제라도 될 수있을 때.Union
-와 달리 지정된 유형의 세트 내에있는 것이있을 수있는 경우Any
.Optional
– 없음 일 때 . 의 속기입니다Union[T, None]
.TypeVar
-제네릭과 함께 사용됩니다.Callable
-주로 함수에 사용되지만 다른 콜 러블에 사용될 수 있습니다.
가장 일반적인 유형 힌트입니다. 전체 목록은 입력 모듈 설명서 에서 찾을 수 있습니다 .
다음은 입력 모듈에 도입 된 주석 방법을 사용하는 이전 예입니다.
from typing import List
def pick(l: List[int], index: int) -> int:
return l[index]
강력한 기능 중 하나 Callable
는 함수를 인수로 취하는 어노테이션이있는 메소드를 입력 할 수있는 기능입니다. 예를 들면 다음과 같습니다.
from typing import Callable, Any, Iterable
def imap(f: Callable[[Any], Any], l: Iterable[Any]) -> List[Any]:
"""An immediate version of map, don't pass it any infinite iterables!"""
return list(map(f, l))
위의 예는 TypeVar
대신에 사용법을 사용하면 더 정확해질 수 Any
있지만, 이미 유형 힌트로 활성화 된 멋진 새로운 기능에 대한 정보를 너무 많이 채워서 믿기 때문에 독자에게 연습으로 남았습니다.
예를 들어 Sphinx 와 같은 문서화 된 Python 코드에서 다음과 같은 형식의 docstring을 작성하면 위의 기능 중 일부를 얻을 수 있습니다.
def pick(l, index):
"""
:param l: list of integers
:type l: list
:param index: index at which to pick an integer from *l*
:type index: int
:returns: integer at *index* in *l*
:rtype: int
"""
return l[index]
보시다시피, 여기에는 여러 줄이 추가로 필요합니다 (정확한 숫자는 명시적인 표현 방법과 문서 문자열의 형식에 따라 다릅니다). 그러나 이제 PEP 3107 이 많은 (모두?) 우월한 대안을 어떻게 제공 하는지 분명히 알 수 있습니다 . 이것은 PEP 484 와 결합하여 특히 그렇습니다. 우리가 살펴본 바와 같이, 이러한 유형 힌트 / 주석에 대한 구문을 정의하는 표준 모듈을 제공하여 명확하고 유연하면서도 유연하게 사용할 수 있습니다. 강력한 조합.
내 개인적인 견해로는 이것이 파이썬에서 가장 큰 기능 중 하나입니다. 사람들이 힘을 활용하기 시작할 때까지 기다릴 수 없습니다. 긴 답변에 대해 죄송하지만 이것이 흥분 될 때 일어나는 일입니다.
답변
유형을 지정하지 않았습니다. 메소드는 전달 된 매개 변수에 정의되지 않은 속성에 액세스하려는 경우에만 런타임에 실패합니다.
따라서이 간단한 기능 :
def no_op(param1, param2):
pass
두 개의 인수가 전달 되더라도 실패하지 않습니다.
그러나이 기능은 다음과 같습니다.
def call_quack(param1, param2):
param1.quack()
param2.quack()
… 경우 런타임에 실패 param1
하고 param2
모두 이름이 호출 속성이 없습니다 quack
.
답변
많은 언어에는 특정 유형의 변수가 있으며 값이 있습니다. 파이썬에는 변수가 없습니다. 여기에는 객체가 있으며 이름을 사용하여 이러한 객체를 나타냅니다.
다른 언어로 말할 때 :
a = 1
그런 다음 (일반적으로 정수) 변수는 내용을 값 1로 변경합니다.
파이썬에서
a = 1
“이름 1 을 사용하여 객체 1 을 참조하십시오 ”를 의미합니다. 대화식 Python 세션에서 다음을 수행 할 수 있습니다.
>>> type(1)
<type 'int'>
함수 type
는 객체와 함께 호출됩니다 1
. 모든 객체는 해당 유형을 알고 있기 때문에 해당 유형 type
을 찾아서 반환하는 것이 쉽습니다 .
마찬가지로 함수를 정의 할 때마다
def funcname(param1, param2):
함수는 두 개의 객체를 수신하고 이름을 param1
하고 param2
자신의 유형에 관계없이. 수신 된 객체가 특정 유형인지 확인하려면 필요한 유형 인 것처럼 함수를 코딩하고 그렇지 않은 경우 발생하는 예외를 포착하십시오. 예외는 일반적으로 TypeError
유효하지 않은 작업 AttributeError
을 사용했으며 존재하지 않는 멤버에 액세스하려고했습니다 (메소드도 멤버 임).
답변
정적 또는 컴파일 타임 유형 검사의 의미에서 파이썬은 강력하게 유형화되지 않습니다.
대부분의 파이썬 코드는 소위 “덕 타이핑 (Duck Typing)”에 속합니다. 예를 들어, read
객체에 대한 메소드를 찾고 있습니다. 객체가 디스크 나 소켓에있는 파일인지 상관하지 않습니다. N 만 읽으려고합니다. 그것의 바이트.
답변
Alex Martelli는 다음 과 같이 설명합니다 .
일반적이고 파이썬적인 선호 솔루션은 거의 항상 “덕핑 타이핑 (duck typing)”입니다. 인자를 마치 원하는 특정 유형 인 것처럼 사용해보십시오. 실제로 인수가 아닌 경우 발생할 수있는 모든 예외를 포착하는 try / except 문에서 시도하십시오. 해당 유형 (또는 다른 유형으로 멋지게 오리를 흉내 내기 ;-)하고 except 절에서 다른 것을 시도하십시오 ( “as as”인수를 사용하여 다른 유형 임).
유용한 정보는 그의 게시물의 나머지 부분을 읽으십시오.
답변
파이썬은 함수에 전달하는 것을 신경 쓰지 않습니다. 을 호출 my_func(a,b)
하면 param1 및 param2 변수가 a 및 b의 값을 보유합니다. 파이썬은 당신이 적절한 타입으로 함수를 호출한다는 것을 알지 못하며 프로그래머가 그것을 처리 할 것으로 기대합니다. 함수가 다른 유형의 매개 변수로 호출되는 경우 try / except 블록으로 액세스하는 코드를 래핑하고 원하는 방식으로 매개 변수를 평가할 수 있습니다.