Câu trả lời ngắn
Bạn đang nhận được kích thước của lớp, không phải là một ví dụ của lớp. Gọi int để có được kích thước của một thể hiện:
>>> sys.getsizeof(int()) 24Nếu kích thước đó vẫn có vẻ hơi lớn, hãy nhớ rằng Python int rất khác với int trong (ví dụ) c. Trong Python, một int là một đối tượng hoàn chỉnh. Điều này có nghĩa là có thêm chi phí.
Mỗi đối tượng Python chứa ít nhất một bản tóm tắt và tham chiếu đến loại của đối tượng ngoài việc lưu trữ khác; Trên một máy 64 bit, điều đó chiếm 16 byte! Nội bộ int (như được xác định bởi việc triển khai CPython tiêu chuẩn) cũng đã thay đổi theo thời gian, do đó lượng lưu trữ bổ sung được thực hiện phụ thuộc vào phiên bản của bạn.
Một số chi tiết về các đối tượng int trong Python 2 và 3
Đây là tình huống trong Python 2. (Một số trong số này được điều chỉnh từ một bài đăng trên blog của Laurent Luce). Các đối tượng số nguyên được biểu diễn dưới dạng các khối bộ nhớ với cấu trúc sau:
typedef struct { PyObject_HEAD long ob_ival; } PyIntObject;typedef struct { PyObject_HEAD long ob_ival; } PyIntObject; 2 là một macro xác định lưu trữ cho loại refcount và loại đối tượng. Nó được mô tả chi tiết bởi tài liệu và mã có thể được nhìn thấy trong câu trả lời này.
Bộ nhớ được phân bổ trong các khối lớn để không có tắc nghẽn phân bổ cho mỗi số nguyên mới. Cấu trúc cho khối trông như thế này:
struct _intblock { struct _intblock *next; PyIntObject objects[N_INTOBJECTS]; }; typedef struct _intblock PyIntBlock;Tất cả đều trống lúc đầu. Sau đó, mỗi khi một số nguyên mới được tạo, Python sử dụng bộ nhớ được trỏ tại typedef struct { PyObject_HEAD long ob_ival; } PyIntObject; 3 và tăng typedef struct { PyObject_HEAD long ob_ival; } PyIntObject; 3 để trỏ đến đối tượng Integer miễn phí tiếp theo trong khối.
Tôi không hoàn toàn chắc chắn làm thế nào điều này thay đổi khi bạn vượt quá khả năng lưu trữ của một số nguyên thông thường, nhưng một khi bạn làm như vậy, kích thước của int sẽ lớn hơn. Trên máy của tôi, trong Python 2:
>>> sys.getsizeof(0) 24 >>> sys.getsizeof(1) 24 >>> sys.getsizeof(2 ** 62) 24 >>> sys.getsizeof(2 ** 63) 36Trong Python 3, tôi nghĩ rằng bức tranh chung là như nhau, nhưng kích thước của các số nguyên tăng theo cách nhiều hơn:
>>> sys.getsizeof(0) 24 >>> sys.getsizeof(1) 28 >>> sys.getsizeof(2 ** 30 - 1) 28 >>> sys.getsizeof(2 ** 30) 32 >>> sys.getsizeof(2 ** 60 - 1) 32 >>> sys.getsizeof(2 ** 60) 36Những kết quả này, tất nhiên, tất cả phụ thuộc vào phần cứng! Ymmv.
Sự thay đổi về kích thước nguyên trong Python 3 là một gợi ý rằng chúng có thể hoạt động giống như các loại có độ dài thay đổi (như danh sách). Và thực sự, điều này hóa ra là đúng. Đây là định nghĩa của C typedef struct { PyObject_HEAD long ob_ival; } PyIntObject; 6 cho các đối tượng int trong Python 3:
struct _longobject { PyObject_VAR_HEAD digit ob_digit[1]; };Các ý kiến đi kèm với định nghĩa này tóm tắt đại diện cho các số nguyên của Python 3. Zero được biểu diễn không phải bằng một giá trị được lưu trữ, mà bởi một đối tượng có kích thước 0 (đó là lý do tại sao typedef struct { PyObject_HEAD long ob_ival; } PyIntObject; 8 là typedef struct { PyObject_HEAD long ob_ival; } PyIntObject; 9 byte trong khi struct _intblock { struct _intblock *next; PyIntObject objects[N_INTOBJECTS]; }; typedef struct _intblock PyIntBlock; 0 là struct _intblock { struct _intblock *next; PyIntObject objects[N_INTOBJECTS]; }; typedef struct _intblock PyIntBlock; 1). Các số âm được biểu thị bằng các đối tượng có thuộc tính kích thước âm! Thật ki cục.
Chúng đại diện cho các số trong phạm vi -2147483648 đến 2147483647. (phạm vi có thể lớn hơn trên các máy có kích thước từ tự nhiên lớn hơn, nhưng không nhỏ hơn.) Khi kết quả của hoạt động sẽ nằm ngoài phạm vi này, kết quả thường được trả về dưới dạng Số nguyên dài (trong một số trường hợp, ngoại lệ Overflowerror được nâng lên thay thế). Đối với mục đích hoạt động thay đổi và mặt nạ, các số nguyên được cho là có một ký hiệu bổ sung nhị phân, 2, sử dụng 32 bit trở lên và ẩn không có bit nào từ người dùng (tức là, tất cả 4294967296 các mẫu bit khác nhau tương ứng với các giá trị khác nhau).
Các số nguyên đơn giản (cũng chỉ được gọi là số nguyên) được triển khai bằng cách sử dụng Long in C, cho chúng ít nhất 32 bit độ chính xác (sys.maxint luôn được đặt thành giá trị số nguyên đơn giản tối đa cho nền tảng hiện tại; giá trị tối thiểu là -sys.maxint - 1). Số nguyên dài có độ chính xác không giới hạn.
Các số được tạo bằng chữ số hoặc là kết quả của các hàm và toán tử tích hợp. Các số nguyên số nguyên chưa được trang trí (bao gồm cả nhị phân, hex và số bát phân) mang lại số nguyên đơn giản trừ khi giá trị mà chúng biểu thị quá lớn để được biểu diễn dưới dạng một số nguyên đơn giản, trong trường hợp chúng mang lại một số nguyên dài. Số nguyên theo nghĩa đen với phần hậu tố ’l, hoặc l, tạo ra các số nguyên dài (’ l, được ưa thích vì 1L trông quá giống với Eleven!).