2016-07-14 10 views
3

나는이 질문을 읽을 수 있지만 그것은 나에게 명확한 답변을주지 않았다 How does Python interpreter look for types?동적 타이핑에서 파이썬 인터프리터는 어떻게 작동합니까?

어떻게 파이썬 인터프리터는 변수의 유형을 알고 않습니다를? 나는 타입을 얻는 방법을 찾고 있지 않습니다. 나는 현장 뒤에서 일어나는 일을보고있다. 아래 예제에서 int 클래스 또는 string을 내 변수에 연결하는 방법은 무엇입니까?

>>> i = 123 
>>> type(i) 
<class 'int'> 

또는 해당 문자열 : 그것이 알고 않는 방법

는 int이며

>>> i = "123" 
>>> type(i) 
<class 'str'> 
+0

@GreenAsJade : OP는 파이썬 3을 사용합니다. 여기서'type' 객체의 표현은''type''이 아닌''class''를 사용합니다; 이것은 C 정의 된 유형이 클래스 일 뿐이라는 것을 반영하기 위해 수행되었습니다. –

+0

@MartijnPieters에는 python3 태그가 필요할 수 있습니다. – GreenAsJade

+0

@GreenAsJade : 아니요, 대답은 파이썬 2와 3에서 동일합니다. 그러나 제공된 결과물은 수정할 필요가 없습니다. –

답변

7

내 변수

파이썬은 그렇지 않습니다. 변수에 유형이 없습니다.. 변수가 참조하는 객체 만 유형을가집니다. 변수는 객체 이름을 가리키는 단순한 입니다.

예를 들어

는, 다음은 객체의 유형을 보여 주지만, 어떤 변수가 포함되지 않은 : 당신이 type(variable) 사용하는 경우

>>> type(1) 
<class 'int'> 
>>> type('foobar') 
<class 'str'> 

는 식의 variable 부분은 단순히 이름을 참조하는 객체를 반환 개체type() 함수로 전달합니다. 1 또는 'foobar'을 사용할 때 표현식은 객체를 생성하는 리터럴이며이 객체는 type() 함수에 전달됩니다.

파이썬 객체는 인터프리터 메모리의 데이터 구조에 불과합니다. CPython C 구조체가 사용됩니다. 변수는 이러한 구조에 대한 참조 (포인터) 일뿐입니다. CPython의 기본 유형 struct는 PyObject이며,이 구조체는 어떤 유형인지를 Python에 알려주는 ob_type slot을 가지고 있습니다. 유형은 간단히 more C structures입니다. 당신이 CPython의 소스 코드를 함께 따라하고 싶다면, defines type as the PyType_Type structure (type가 내장 된 이름이기 때문에)

, 당신은 bltinmodule.c source code에서 시작했으면합니다. 유형을 (type가 너무 유형입니다)를 호출하면 자신의 tp_new function 호출하고 the type_new functionPyType_Typedefines that. 이 함수는 다음과 같이 인수 호출을 처리 : 여기 x

/* Special case: type(x) should return x->ob_type */ 
{ 
    const Py_ssize_t nargs = PyTuple_GET_SIZE(args); 
    const Py_ssize_t nkwds = kwds == NULL ? 0 : PyDict_Size(kwds); 

    if (PyType_CheckExact(metatype) && nargs == 1 && nkwds == 0) { 
     PyObject *x = PyTuple_GET_ITEM(args, 0); 
     Py_INCREF(Py_TYPE(x)); 
     return (PyObject *) Py_TYPE(x); 
    } 

이 전달 된 PyObject 목적은; 변수가 아니라 객체라는 점에주의하십시오! 따라서 1 정수 객체 또는 'foobar' 문자열 객체의 경우 Py_TYPE() 매크로 결과가 반환됩니다. Py_TYPE is a macro은 단순히 구조체의 ob_type 값을 반환합니다.

이제는 1 또는 'foobar' 중 하나의 개체 유형이 있습니다. 인터프리터 세션에서 <class 'int'> 또는 <class 'str'>을 어떻게 볼 수 있습니까? 파이썬 대화 형 인터프리터는 모든 표현식 결과에 자동으로 repr() function을 사용합니다. PyType_Type 정의에 대한 C 구조에서는 PyType_Type 구조체가 통합되어 해당 유형의 모든 슬롯을 직접 사용할 수 있습니다. 정확히 인 방법을 생략 할 것입니다. type(1)은 (파이썬 3, 긴 이야기의 PyLong_Type struct 것으로 판명)를 ->ob_type 슬롯을 가져옵니다, 결국

rtn = PyUnicode_FromFormat("<class '%s'>", type->tp_name); 

그래서, 그리고 : 유형 오브젝트를 들어, repr()을 사용하면 type_repr function이 반환이라고 의미 해당 구조는 tp_name slot set to "int"입니다.

TL : DR : 파이썬 변수에는 유형이 없으며 단순히 객체에 대한 포인터입니다. 객체에는 유형이 있으며, 인터프리터에서 객체를 반향 출력하는 경우 인쇄 할 유형 이름에 도달하기 위해 Python 인터프리터가 일련의 간접 참조를 따릅니다.

0

변수의 개념 "유형"는 특정 클래스의 객체를 사용하여 "구현"입니다 .

그래서 클래스 float에 의해 정의 된

a=float()

유형 float의 객체

float()에 의해 반환됩니다. 파이썬은 객체가 작동하는 방식이기 때문에 어떤 유형인지 알고 있습니다. 유형이 무엇인지 알기 때문입니다. a은 이제 float 개체이며 값은 0.0입니다.

builtins를 사용하면 같은 것을 선언 할 수 있습니다.

i=123

값 123

마찬가지로

i="123"

으로

Integer 클래스의 객체를 반환 i=int(123)

int()와 동일

는 값으로,

i=str("123")

str("123") 클래스 STR의 객체를 반환과 동일 "123"은에 클래스 INT 또는 문자열을 연결 않는 방법

0

파이썬 변수는 유형이 없으며 객체에 대한 참조 일뿐입니다. 참조의 크기는 참조하는 내용과 관계없이 동일합니다.파이썬의 C 구현에서 그것은 포인터이고, 에 타입이 있습니다. 파이썬 객체에 대한 포인터는 PyObject *입니다. 포인터는 객체 클래스에 관계없이 같은 유형입니다. 반면에 객체는 어느 클래스에 속하는지 알 수 있습니다.

파이썬에는 변수가 없으며 대부분의 사람들에게 너무 먼 단계입니다.

CPython 구현의 참조에는 실제로 가상 주소 인 ID (식별자)가 있습니다. 이 주소의 세부 사항 및 가치는 추구할만한 가치가 없습니다. 버전간에 변경 될 수 있으며 (아마도 가능할 것입니다) 객체를 식별하는 고유 번호 이외의 다른 용도로 사용되지 않습니다. 무슨 일이 일어나고 있는지 그럼에도 불구하고 흥미 포인터를 (잘났어) 제공 할 수 xy의 ID (주소)가 동일한 지

>>> x = 42 
>>> y = x 
>>> id(x) 
4297539264 
>>> id(y) 
4297539264 

주 -가 같은 객체를 참조하고이 값과 int을 따라서 우리가 x을 변경할 때 y도 변경됩니까?

>>> x = "hello" 
>>> id(x) 
4324832176 
>>> id(y) 
4297539264 

고맙게도. 이제 x은 값이 "Hello"인 클래스 str의 새 객체를 나타냅니다.

>>> id(y) 
4297539264 
>>> y = 37 
>>> id(y) 
4297539104 

y의 ID가 변경 : 우리가

! 이것은 이제 다른 객체를 참조하기 때문입니다. int이 아니며 임으로 할당 y = 37은 원래 오브젝트 (42)를 새로 변경하지 않았습니다. 값이 42 인 객체는 참조 카운트가 감소하고 이제 (이론적으로) 삭제 될 수 있습니다. 실제로는 효율성상의 이유로 메모리에 남아 있지만 구현 세부 사항은 그대로 유지됩니다. 그러나

:

>>> a = [1,2,3,4] 
>>> b = a 
>>> id(a) 
4324804808 
>>> id(b) 
4324804808 
>>> a[0] = 99 
>>> b 
[99, 2, 3, 4] 

그래서 a b을 변경 목록을 변경! 이는 목록이 로 변경 될 수 있기 때문에 변경 될 수 있습니다. 할당 b = a은 목록이 아닌 참조 만 복사했습니다. 표준 라이브러리의 copy을 참조하십시오.