2016-03-14 15 views
14

Hãy tưởng tượng một hàm động thêm thuộc tính vào đối tượng sử dụng setattr. Lý do để làm như vậy là tôi muốn để ánh xạ một số cấu trúc bên ngoài (ví dụ như một cây thông số nhất định) cho một đối tượng:Tránh cảnh báo Pylint E1101: 'Sơ đồ .. không có thành viên ..' cho lớp có thuộc tính động

my_object = SomeClass() 
apply_structure(my_object, some_descriptor) 
my_object.device1.enabled = True 

Về mặt kỹ thuật các công trình này nhưng tất nhiên pylint đúng phàn nàn về 'DEVICE1' là không phải là một thành viên của SomeClass.

Tôi có thể tắt cảnh báo nhưng điều đó sẽ là xấu (vì tôi vẫn muốn nhận cảnh báo trong mọi trường hợp khi thuộc tính không tồn tại do lỗi chính tả, v.v.).

Có cách nào phổ biến và hợp pháp (Pylint-proof) để tự động thêm thành viên vào đối tượng không dẫn đến cảnh báo?

Cách khác: Tôi có thể tắt Pylint chỉ cho một đối tượng thay vì dòng/khối/tệp không?

Giải thích:

Bạn có thể tự hỏi tại sao tôi nên trang bị cho một đối tượng với thành viên thuộc tính tự động khi tôi có kế hoạch để truy cập các thuộc tính trong một cách mã hóa cứng sau.

Lý do là: Tôi có phần động của chương trình (nơi trang trí xảy ra) và phần tĩnh là chuyên cho một số trường hợp nhất định. Vì vậy, tôi có thể cũng tạo một lớp tĩnh cho trường hợp này nhưng điều đó sẽ là quá mức cần thiết trong nhiều trường hợp.

Sau đây chuyên mã có thể cho phép truy cập vào một số thông số của một thiết bị mà có thể được gắn vào một số xe buýt:

class MyDeviceHandler: 
    on_get_some_subtree_element(self): 
     return _some_internal_value 
    on_set_some_subtree_element(self, value): 
     _some_internal_value = value 

dev = MyDeviceHandler() 

decorate_object_with_device_structure(dev, 'some/attached/device') 

dev.some.subtree.element = 5  <--- will call the set-callback 
x = dev.some.subtree.element  <--- will call the get-callback 

Vì vậy, cấu trúc đằng sau 'some/attached/device' có thể tùy ý và rất phức tạp và tôi không muốn tái tạo nó trong một cấu trúc lớp học.

Một cách để thoát khỏi cảnh báo này sẽ được tạo/truy cập vào một cây dict dựa trên:

dev['some']['subtree']['element'] = 5 

Nhưng điều này là khó khăn hơn để viết và không thoải mái để đọc - Tôi sẽ chỉ làm điều này để yên ổn pylint .

+0

Câu hỏi của tôi là, nếu bạn biết trước cấu trúc mà bạn muốn truy cập, tại sao không xác định cấu trúc đó một cách rõ ràng trong địa điểm đầu tiên? – nthall

+1

Đó chính là vấn đề. Tôi không biết. Trên thực tế tôi đọc một cấu trúc từ một cây bất động sản thiết bị (có thể là bất cứ điều gì) và tôi xây dựng một đối tượng Python.Tôi sẽ giải thích thêm về vấn đề này một chút trong câu hỏi .. – frans

+3

Bạn có thể đặt các tùy chọn 'created-members' hoặc' ignored-classes' [cho pylint] (https://docs.pylint.org/features.html# id28) (trên dòng lệnh, hoặc dưới '[TYPECHECK]' trong một '.pylintrc') –

Trả lời

13

Chỉ cần để cung cấp câu trả lời làm việc cho tôi bây giờ - như The Compiler gợi ý bạn có thể thêm một quy tắc cho các lớp có vấn đề trong dự án của bạn .pylintrc:

[TYPECHECK] 
ignored-classes=Fysom,MyClass 
0

Bạn có thể sử dụng một lớp con:

class MyClass(Someclass): 
    def init(self): 
     super().__init__() 
     self.device1 = WhateverDevice1Is() 

my_object = MyClass() 
apply_structure(my_object, some_descriptor) 
my_object.device1.enabled = True 

Lưu ý: Python3

+0

Điều này sẽ chỉ di chuyển vấn đề từ 'MyClass' thành' WhateverDevice1Is' (cũng phải được tạo động). Tôi đã thêm một số giải thích cho câu hỏi của tôi .. – frans

+0

Nhưng định nghĩa lớp thiết bị của bạn được biết đến ở thời gian nhập, phải không? Bạn có bao nhiêu loại thiết bị khác nhau? Điều kỳ lạ đối với tôi là bạn muốn sử dụng các thuộc tính (không có setattr()) có nghĩa là bạn biết tên và số thuộc tính khi bạn viết mã của mình. Từ khoản khấu trừ này, nếu bạn muốn mã sạch, bạn sử dụng các lớp con trong mẫu cấu trúc Adapater/Proxy hoặc cuối cùng được đặt tên làtuple. – Maresh

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