2011-05-10 33 views
11

Tôi đã rối tung với các thuộc tính động và tôi nhận thấy tôi không thể sử dụng thuộc tính __dict__ nếu tôi tạo đối tượng trực tiếp từ lớp object() nhưng nếu tôi tạo một lớp mới là một hậu duệ trực tiếp của đối tượng mà tôi có thể truy cập thuộc tính __dict__. Tại sao sự khác biệt?Trong Python khác biệt trong __dict__ giữa object() và class myClass (object)

Ví dụ:

# This gives an AttributeError 
o = object() 
o.__dict__ 
# This works: prints {} 
class myClass(object): 
    pass 
o = myClass() 
o.__dict__ 
+0

Việc không quan tâm đến '__dict__' trực tiếp hầu như không cần thiết và là một ý tưởng tồi. Tên thuộc tính động thường được thực hiện tốt hơn như các khóa từ điển, nhưng được chứng minh trong một vài trường hợp - nhưng bạn chỉ có thể sử dụng 'setattr' trong những trường hợp đó. – delnan

Trả lời

8

object được thực hiện trong C và không có một thuộc tính __dict__. (Không phải tất cả các đối tượng Python đều có, tra cứu __slots__).

+0

@Jamie Lưu ý rằng bạn không thể gán các thuộc tính ngẫu nhiên trên một cá thể thu được bằng cách thực hiện 'object()', hoặc là, trong khi bạn có thể với một cá thể 'myClass'. Trong thực tế không có nhiều bạn * có thể * làm với một thể hiện của 'đối tượng' mà không phải là một thể hiện của bất kỳ lớp nào khác. – Ben

1

Tôi không hoàn toàn chắc chắn lý do tại sao nó hoạt động cho lớp học của bạn chứ không phải lớp gốc object. Tôi cho rằng khi lớp của bạn được khởi tạo, nó sẽ tạo __dict__.

Sử dụng mã này:

class Test(object): 
    def __init__(self): 
     pass 

def main(): 
    print 'OBJECT:', dir(object()) 
    print 
    print 'TEST:', dir(Test()) 
    return 

Came lên với sản lượng này:

OBJECT: ['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__'] 

TEST: ['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__'] 

Như bạn thấy, __dict__, __module__, và __weakref__ là trong đối tượng thử nghiệm nhưng không phải là đối tượng cơ sở

+2

Đó là một phần vốn có của Python - tùy thuộc vào định nghĩa lớp có hay không họ muốn cung cấp thuộc tính __dict__ hoặc không (để nó có thể tiết kiệm một chút không gian công bằng cho mỗi trường hợp). Vì __dict__ được bao gồm trong các trường hợp theo mặc định, bạn phải thực hiện hành động cụ thể ở thời gian định nghĩa lớp để tránh cung cấp một. – ncoghlan

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