Là sửa đổi __dict__ của một đối tượng để đặt các thuộc tính của nó được coi là Pythonic?


12

Tôi có một lớp làm tăng các đối tượng từ các hàng được tìm thấy trong cơ sở dữ liệu (hoặc một nguồn khác, ví dụ MongoDB, tệp CSV, v.v.). Để thiết lập các thuộc tính của đối tượng, nó thực hiện một số thứ như self.__dict__.update(**properties)hoặc obj.__dict__.update(**properties).

Đây có được coi là Pythonic? Đây có phải là một mẫu tốt mà tôi nên tiếp tục sử dụng, hay đây được coi là hình thức xấu?


1
Tôi không biết nếu đó là Pythonic, nhưng chắc chắn sẽ phổ biến hơn khi thực hiện nó trong dunder init.
dùng16764

Câu trả lời:


10

Trong Python 3.3, một loại mới đã được thêm vào types.SimpleNamespace()và trong tài liệu này, nó được mô tả như sau:

Loại này tương đương với mã sau đây:

class SimpleNamespace:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
    def __repr__(self):
        keys = sorted(self.__dict__)
        items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
        return "{}({})".format(type(self).__name__, ", ".join(items))

Lưu ý __init__phương pháp của loại; bạn không thể có được sự chứng thực kỹ thuật tốt hơn tài liệu Python.


Mặc dù SimpleNamespacekhá khác biệt so với hầu hết các loại ở chỗ nó không có một bộ thuộc tính cố định.

7
Chà, nói về tài liệu Python, từ docs.python.org/2/l Library / stdtypes.html "Một thuộc tính đặc biệt của mọi mô-đun là __dict__. Đây là từ điển chứa bảng biểu tượng của mô-đun. Sửa đổi từ điển này sẽ thực sự thay đổi biểu tượng của mô-đun bảng, nhưng __dict__không thể gán trực tiếp cho thuộc tính (bạn có thể viết m.__dict__['a'] = 1, định nghĩa m.alà 1, nhưng bạn không thể writem.__dict__ = {}). Sửa đổi __dict__trực tiếp không được khuyến nghị ", đó là điều ban đầu khiến tôi phải hỏi câu hỏi này.
skyler

@skyler: lưu ý rằng chỉ đề cập đến không gian tên mô-đun . Các globals()hàm trả về không gian tên giống nhau, và có những cách thường tốt hơn để giải quyết vấn đề hơn so với thiết globals động, vì thế mà cảnh báo.
Martijn Pieters
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.