Python 소스 코드 학습 의 PyObject 와 PyTypeObject

머리말
Python 은 C 언어 로 이 루어 졌 기 때문에 Python 대상 은 C 언어 차원 에서 하나의 구조 체 이 고 조직 대상 이 차지 하 는 메모리 여야 합 니 다.서로 다른 유형의 대상,데이터 와 행위 가 다 를 수 있 기 때문에 서로 다른 유형의 대상 은 서로 다른 구조 체 에 의 해 표 시 될 수 있다 고 대담 하 게 추측 할 수 있다.
대상 도 일부 공통점 이 있다.예 를 들 어 모든 대상 은 하나의 인용 계 수 를 가지 고 쓰레기 회수 체 제 를 실현 해 야 한다.따라서 대상 의 구조 체 에 공공 머리 가 있다 는 추측 도 가능 하 다.
1.실례 대상 의 초석-PyObject 와 PyVarObject
PyObject 와 PyVarObject 는 본질 적 으로 대상 의 머리 정보 이다.
1.1 PyObject 구조 체
Python 대상 은 모두 PyObject 구조 체 에 의 해 표시 되 고 대상 인용 은 지침 PyObject * 이다.PyObject 구조 체 는 헤더 파일 object.h 에 정의 되 고 경 로 는 Include/object.h 이 며 코드 는 다음 과 같 습 니 다.

typedef struct _object {
    _PyObject_HEAD_EXTRA
    Py_ssize_t ob_refcnt;
    struct _typeobject *ob_type;
} PyObject;
구조 체 중의 원 소 를 설명 하고,
요소 이름
설명 하 다.
ob_refcnt
인용 계수,대상 이 다른 곳 에서 인용 되 었 을 때 하 나 를 추가 하고 인용 해제 시 하 나 를 줄 입 니 다.인용 계수 가 0 이면 대상 을 회수 할 수 있 는데 이것 은 가장 간단 한 쓰레기 회수 메커니즘 이다.
ob_type
형식 포인터 가 대상 의 유형 대상 을 가리 키 고 유형 대상 은 인 스 턴 스 대상 의 데이터 와 행 위 를 설명 합 니 다.
_PyObject_HEAD_EXTRA
매크로,include/object.h 헤더 파일 에 정의 합 니 다.
1.2 매크로 의 정의

#ifdef Py_TRACE_REFS
/* Define pointers to support a doubly-linked list of all live heap objects. */
#define _PyObject_HEAD_EXTRA            \
    struct _object *_ob_next;           \
    struct _object *_ob_prev;

#define _PyObject_EXTRA_INIT 0, 0,

#else
#define _PyObject_HEAD_EXTRA
#define _PyObject_EXTRA_INIT
#endif
Py_TRACE_REFS 이 정의 되면 매크로 는 두 개의 포인터 ob_nextob_prev 으로 양 방향 링크 를 실현 합 니 다.설명 에 따 르 면 양 방향 링크 는 모든 활성 화 된 대상 을 추적 하 는 데 사 용 됩 니 다.일반적으로 사용 하지 않 고 깊이 소개 하지 않 습 니 다.
1.3 PyVarObject 구조 체
길 어 지 는 대상 을 나타 내 는 PyVarObject 구조 체 는 PyObject 구조 체 를 바탕 으로 길이 정 보 를 넣는다.

typedef struct {
    PyObject ob_base;
    Py_ssize_t ob_size; /* Number of items in variable part */
} PyVarObject;
object 구조 체 에 비해 ob_size 필드 가 증가 하여 원소 개 수 를 기록 하 는 데 사용 되 었 다.
Alt
1.4 두 가지 머리 정보 매크로 정의 와 초기 화
구체 적 인 실례 대상 은 메모리 크기 가 고정 되 어 있 는 지 여 부 를 보고 정 해진 대상 에 속 하 는 지,아니면 길 어 지 는 대상 에 속 하 는 지 결정 한다.이에 따라 두부 정보 PyObject 또는 PyVarObject 이 필요 하 다.
따라서 헤더 파일 은 두 개의 헤드 정보의 매크로 정의 PyObject_HEADPyObject_VAR_HEAD 을 준비 하여 대상 이 사용 하기에 편리 하 다.

#define PyObject_HEAD          PyObject ob_base;
#define PyObject_VAR_HEAD      PyVarObject ob_base;
매크로 정의 설명,

#define PyObject_HEAD PyObject ob_base;
          PyObject_HEAD   ,   PyObject ob_base;
1.4.1 고정 대상 실현
메모리 크기 가 고정된 부동 소수점 류 의 실현 은 PyObject 머리 를 바탕 으로 쌍 정밀도 부동 소수점 double 로 이 루어 져 야 합 니 다.

typedef struct {
    PyObject_HEAD

    double ob_fval;
} PyFloatObject;
Alt
1.4.2 길 어 지 는 대상 실현
메모리 크기 가 고정 되 지 않 은 목록 대상 은 PyVarObject 머리 를 바탕 으로 동적 배열 로 이 루어 져 야 합 니 다.배열 저장 목록 에 포 함 된 대상,즉 PyObject 지침 입 니 다.

typedef struct {
    PyObject_VAR_HEAD

    PyObject **ob_item;
    Py_ssize_t allocated;
} PyListObject;
Alt
PyList Object 바 텀 은 하나의 배열 로 이 루어 집 니 다.관건 적 인 필드 는 다음 과 같은 3 개 입 니 다.
필드
설명 하 다.
ob_item
동적 배열 을 가리 키 는 지침,배열 은 요소 대상 지침 을 저장 합 니 다.
allocated
동적 배열 의 총 길이,즉 목록 의 현재 용량 입 니 다.
ob_size
현재 요소 갯 수,즉 목록 의 현재 길이 입 니 다.
목록 용량 이 부족 할 때 Python 은 자동 으로 용량 을 확대 합 니 다.구체 적 인 메커니즘 은 list 소스 코드 를 참조 하여 해석 합 니 다.
1.4.3 헤드 정보 매크로 초기 화PyObject_HEAD_INIT 은 대상 의 머리 정 보 를 초기 화 하 는 데 사 용 됩 니 다.인용 계수 ob_refcnt 을 1 로 설정 하고 대상 유형 ob_type 을 주어진 형식 으로 설정 합 니 다.

#define PyObject_HEAD_INIT(type)        \
    { _PyObject_EXTRA_INIT              \
    1, type },
PyVarObject_HEAD_INIT 은 길 어 지 는 대상 의 머리 정보 초기 화 에 사용 된다.전 자 를 바탕 으로 길이 필드 ob_size 을 추가 로 설정 합 니 다.

#define PyVarObject_HEAD_INIT(type, size)       \
    { PyObject_HEAD_INIT(type) size },
원본 코드 에서 이 두 매크로 정 의 를 자주 볼 수 있 습 니 다.
2.유형 대상 의 초석-PyTypeObject 2.1 PyTypeObject 는 정 보 를 포함 합 니 다.PyObject 은 Python 의 모든 대상 이 공유 하 는 정 보 를 기록 했다.예 를 들 어 인용 계수,유형 포인터 와 길 어 지 는 대상 특유 의 요소 갯 수 입 니 다.하지만 아직 고려 해 야 할 세부 사항 이 있다.
  • 서로 다른 유형의 대상 을 만 들 때 대상 이 필요 로 하 는 메모리 정 보 를 어떻게 알 수 있 습 니까?
  • 특정한 대상 을 정 하고 어떤 조작 을 지원 하 는 지 어떻게 판단 합 니까?
  • 이러한 대상 으로서 의 메타 정 보 는 하나의 독립 된 실체 로 저장 되 어야 하 며 대상 이 속 한 유형 과 밀접 한 관 계 를 가진다.PyObject 에 포 함 된 ob_type 지침 은 하나의 유형 대상 을 가리킨다.유형 대상 PyTypeObjectInclude/object.h 에서 정 의 했 고 관건 적 인 필드 는 다음 과 같다.
    
    typedef struct _typeobject {
        PyObject_VAR_HEAD
        const char *tp_name; /* For printing, in format "<module>.<name>" */
        Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */
    
        /* Methods to implement standard operations */
        destructor tp_dealloc;
        printfunc tp_print;
    
        getattrfunc tp_getattr;
        setattrfunc tp_setattr;
    
        // ...
        /* Attribute descriptor and subclassing stuff */
        struct _typeobject *tp_base;
    
        // ......
    } PyTypeObject;
    
    유형 대상 PyTypeObject 은 길 어 지 는 대상 으로 길 어 지 는 대상 의 머리 정보 PyObject_VAR_HEAD 과 전용 필드 를 포함한다.
    필드
    설명 하 다.
    형식 이름
    tp_name 필드
    유형의 상속 정보
    tp_base 필드 지향 기본 클래스 대상
    인 스 턴 스 대상 을 만 들 때 필요 한 메모리 정보
    tp_basicsize 와 tpitemsize 필드
    이 형식 이 지원 하 는 작업 정보
    tp_print、tp_getattr 등 함수 포인터PyTypeObject 은 유형 대상 이 Python 에서 의 표현 형식 으로 대상 을 대상 으로 하 는'클래스'의 개념 에 대응 하고 있다.PyTypeObject 구 조 는 매우 복잡 하 므 로 현재 대상 의 메타 정 보 를 저장 하고 대상 의 유형 을 묘사 하면 된다.
    2.2 유형 대상 과 인 스 턴 스 대상 이 메모리 에서 의 관계
    float 를 예 로 들 어 유형 대상 과 인 스 턴 스 대상 이 메모리 에 있 는 형태와 관 계 를 고찰 합 니 다.
    
    >>> float
    <class 'float'>
    >>> pi = 3.14
    >>> e = 2.71
    >>> type(pi) is float
    True
    Alt
  • 두 float 인 스 턴 스 대상 은 모두 PyFloatObject 구조 체 로 공공 머리 필드 ob_refcntob_type 을 제외 하고 전용 필드 ob_fval 은 해당 하 는 수 치 를 저장 했다.
  • 유형 대상 은 PyTypeObject 구조 체 로 유형 명,메모리 배분 정보 와 부동 소수점 관련 작업 을 저장 했다.인 스 턴 스 대상 의 ob_type 필드 는 유형 대상 을 가리 키 고 Python 은 이에 따라 대상 유형 을 판단 하여 대상 에 대한 메타 정 보 를 알 수 있 습 니 다.
  • float,pi 와 e 등 변 수 는 실제 대상 을 가리 키 는 지침 일 뿐이다.
  • 위의 그림 의 내용 은 완전히 정확 하지 않 고 뒤의 박문 을 더욱 깊이 해석 할 수 있다.
    파 이 썬 소스 코드 학습 에 관 한 PyObject 와 PyTypeObject 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 PyObject 와 PyTypeObject 에 관 한 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기