2009-10-19 32 views
5

Tôi có một Monostate cơ bản với Python 2.6.Cảnh báo Ngừng sử dụng Python với Monostate __new__ - Ai đó có thể giải thích lý do tại sao?

class Borg(object): 
    __shared_state = {} 
    def __new__(cls, *args, **kwargs): 
     self = object.__new__(cls, *args, **kwargs) 
     self.__dict__ = cls.__shared_state 
     return self 

    def __init__(self, *args, **kwargs): 
     noSend = kwargs.get("noSend", False) 
     reportLevel = kwargs.get("reportLevel", 30) 
     reportMethods = kwargs.get("reportMethods", "BaseReport") 
     contacts= kwargs.get("contacts", None) 

a = Borg(contacts="Foo", noSend="Bar",) 

nào hạnh phúc mang lại cho tôi những cảnh báo Deprecation sau ..

untitled:4: DeprecationWarning: object.__new__() takes no parameters 
    self = object.__new__(cls, *args, **kwargs) 

Sau một chút googling Tôi tìm thấy điều này được gắn vào Bug #1683368. Điều tôi không thể hiểu được là điều này có ý nghĩa gì. Khiếu nại về dòng sau

self = object.__new__(cls, *args, **kwargs) 

Điều này có vẻ ổn. Ai đó có thể giải thích trong các điều khoản laymens tại sao đây là sự cố. Tôi hiểu rằng "điều này không phù hợp với các danh sách tích hợp khác, như danh sách" nhưng tôi không chắc tôi hiểu tại sao. Có ai đó giải thích điều này cho tôi thấy đúng cách để làm điều đó?

Cảm ơn

Trả lời

1

Cảnh báo xuất phát từ thực tế là __new__() thể CÓ args, nhưng vì họ đang bị bỏ qua ở khắp mọi nơi, đi qua args (trừ cls) để nó gây ra cảnh báo. Nó không thực sự (hiện tại) một lỗi để vượt qua các args phụ, nhưng chúng không có hiệu lực.

Trong py3k nó sẽ trở thành một lỗi để vượt qua các arg.

+0

Tôi đang thất bại trong việc xem cách họ bị bỏ qua? Đưa ra * args và ** kwargs từ mới và nó sẽ bom vì chúng là cần thiết bởi __init__ đang mong đợi chúng. Bạn tuyên bố cuối cùng là một trong những tôi đang cố gắng để ngăn chặn :-) Tôi muốn nó làm việc trong 3k. – rh0dium

+0

Tôi không thể tranh cãi với các nhà thiết kế ngôn ngữ. Nếu họ nói "mới không có bất kỳ đối số", tôi làm cho nó không có đối số. '__init__' và' __new__' hoạt động tương tự, có lẽ trường hợp sử dụng của bạn nên sử dụng init thay vì mới. –

6

Xem python-singleton-object-instantiation, và lưu ý Alex Martelli's dụ singleton:

class Singleton(object): 

    __instance = None 

    def __new__(cls): 
     if cls.__instance == None: 
      __instance = type.__new__(cls) 
      __instance.name = "The one" 
     return __instance 

Câu hỏi __new__ deprecationanswered by Guido:

Thông điệp có nghĩa chỉ là những gì nó nói. :-) Không có điểm nào trong việc gọi đối tượng .__ new __() với nhiều tham số lớp và bất kỳ mã nào mà làm như vậy chỉ là đổ những arg đó vào một lỗ đen.

Thời gian duy nhất khi nó có ý nghĩa cho đối tượng .__ __ mới() để bỏ qua thêm lập luận là khi nó không bị ghi đè, nhưng __init__ được ghi đè - sau đó bạn có một __new__ hoàn toàn mặc định và kiểm tra các đối số hàm tạo được chuyển xuống __init__.

Mục đích của tất cả điều này là để bắt lỗi trong một cuộc gọi như đối tượng (42) mà (một lần nữa) vượt qua một đối số không được sử dụng. Đây là thường là một triệu chứng của một lỗi trong chương trình của bạn.

--Guido

+0

Đó là một singleton (aka highlander) không phải là một borg (monostate). Tôi đã [học] [1] rồi.Tôi cũng đã sẵn sàng nhận xét của Guido nhưng như tôi đã nói trước đó nếu init của bạn có yêu cầu của * args ** kwargs thì __new__ cũng sẽ yêu cầu họ? Đúng?? [1]: http://stackoverflow.com/questions/1575680/ensure-that-only-one-instance-of-a-class-gets-run – rh0dium

+0

Xin lỗi phần chữ đậm và liên kết bị rối tung lên .. – rh0dium

+0

Guido nói rõ ràng rằng chỉ __init__ là bắt buộc để kiểm tra các đối số hàm tạo. – gimel

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