2013-05-12 31 views
7

Nếu chúng ta so sánh danh sách được tạo ra bằng cách áp dụng dir() built-in cho các đối tượng lớp cha và một 'giả', lớp bodyless, chẳng hạn nhưCác lớp học có các thuộc tính '__dict__' mặc định của họ từ đâu?

class A(): 
    pass 

chúng tôi thấy rằng Một lớp học có ba thuộc tính ('__dict__', '__module__' and '__weakref__') mà không có mặt trong lớp đối tượng.

Lớp A kế thừa các thuộc tính bổ sung này từ đâu?

+0

Từ cha mẹ của tất cả, 'đối tượng'. –

Trả lời

8
  • Thuộc tính __dict__ được tạo bởi mã nội bộ trong type.__new__. Metaclass của lớp có thể ảnh hưởng đến nội dung cuối cùng của __dict__. Nếu bạn đang sử dụng __slots__, bạn sẽ không có thuộc tính __dict__.

  • __module__ được đặt khi lớp được biên dịch, vì vậy cá thể kế thừa thuộc tính này từ lớp. Bạn có thể xác minh điều này bằng cách thực hiện kiểm tra inst.__module__ is cls.__module__ (với điều kiện inst là một phiên bản cls) và cũng bằng cách sửa đổi cls.__module__ và quan sát rằng inst.__module__ phản ánh thay đổi này.

    (bạn cũng có thể làm những việc ngu ngốc như thiết inst.__module__ đến một giá trị khác nhau từ cls.__module__ Không chắc tại sao điều này không phải là một thuộc tính chỉ đọc..)

  • __weakref__ được tạo ra khi các trường hợp là; AFAIK hoàn toàn được kiểm soát bởi hệ thống tạo đối tượng CPython bên trong. Thuộc tính này chỉ xuất hiện trên các trường hợp của các lớp con object - ví dụ: các trường hợp của int, list, set, tuple không có thuộc tính __weakref__.

    Khi diễn giải giải thích này, hãy nhớ rằng class C: tương đương với class C(object): cho Python3. Đối với Python2, đồng bằng class C: sẽ tạo các trường hợp không có __weakref__ (hoặc một số thuộc tính khác có được từ triển khai object).

+1

'__dict__' được đặt bởi' loại .__ new__'. Giá trị được trả về bởi phương thức metaclass ''__prepare__' được truyền vào phương thức metaclass'' __new__' (hầu như luôn luôn được chuyển tới 'type .__ new__' nếu một lớp mới thực sự được tạo ra). Và 'loại .__ new__' than phiền nếu bạn cho nó bất cứ điều gì khác hơn là một dict thực tế. Vì vậy, bất kỳ '__prepare__' trả về nào cũng không ảnh hưởng đến thuộc tính' __dict__' thực tế nào, nó chỉ được sử dụng để tích lũy * nội dung * mà cuối cùng sẽ được thêm vào '__dict__'. Python2 là như nhau, nhưng bạn không thể chọn bộ sưu tập tích lũy. – Ben

+0

@Ben: Cảm ơn, tôi đã làm rõ rằng – kampu

+2

"Trong diễn giải giải thích này, hãy nhớ rằng' lớp C: 'tương đương với' lớp C (đối tượng): '" - chỉ đúng với Py3, không phải cho Py2. – glglgl

Các vấn đề liên quan