Là ** kwargs một antipotype?


15

Chúng tôi có rất nhiều mã trong cơ sở mã nội bộ gọi các thư viện của chúng tôi bên trong - các thư viện này thường có rất nhiều đối số (nghĩ là matplotlib) và mã của chúng tôi thường chỉ thực hiện một tác vụ cụ thể và chỉ đơn giản chuyển **kwargssang hàm tiếp theo được gọi.

Ví dụ:

def our_method(dataframe, **kwargs):
    result = do_something_with_data(dataframe)
    external_module.draw(result, **kwargs)

Mặc dù **kwargsngăn chúng tôi lặp lại tất cả các tham số trong khai báo phương thức của chúng tôi, nhưng nó cũng làm cho nó cực kỳ mờ đối số nào là hợp lệ khi gọi our_method- tôi phải biết phương thức nào được gọi, mà tôi thường không muốn biết.

Ông nghĩ sao về điều này là gì?

Câu trả lời:


15

Mã của bạn được các nhà phát triển sử dụng như thế nào? Nói cách khác, chính xác họ làm gì để xác định nên sử dụng đối số nào và làm thế nào?

  • Nếu họ dựa vào tài liệu được tạo tự động từ mã của bạn và trình tạo không biết phải làm gì **kwargs, thì đây thực sự là vấn đề. Thay vì tìm danh sách các đối số và ý nghĩa của chúng trong tài liệu, chúng hoàn toàn không có thông tin nào ngoại trừ việc mơ hồ, nó cần một số đối số.

    Vấn đề này có thể được giải quyết bằng cách ghi lại phương pháp theo cách thủ công, thay thế tài liệu được tạo tự động. Điều này đòi hỏi công việc bổ sung từ người thực hiện phương thức, nhưng hãy nhớ rằng, mã (và tài liệu của nó) được đọc thường xuyên hơn nhiều so với nó được viết.

  • Nếu mã là tài liệu của họ, các nhà phát triển sử dụng phương thức **kwargscần hai bước bổ sung: họ không chỉ cần nhìn vào chữ ký của phương thức mà còn cả việc triển khai thực tế của nó, để tìm phương thức khác mà nó thực sự gọi. Sau đó, họ cần phải đi đến phương pháp khác này để cuối cùng tìm thấy những gì họ đang tìm kiếm.

    Điều này không liên quan đến nhiều nỗ lực, nhưng vẫn vậy, nỗ lực nên được lặp đi lặp lại nhiều lần. Điều tồi tệ nhất là bạn không thể giúp họ bằng cách thêm tài liệu: nếu bạn nhận xét phương pháp của mình, liệt kê các đối số thực tế, có một rủi ro lớn là phiên bản tiếp theo của thư viện mà các cuộc gọi phương thức của bạn sẽ có các đối số khác nhau và tài liệu của bạn sẽ đã lỗi thời, vì không ai sẽ nhớ rằng nó cần được cập nhật.

Đề nghị của tôi là chỉ dựa vào **kwargscác phương pháp có phạm vi giảm. Các phương thức riêng tư (và riêng tư trong ngữ cảnh của Python, ý tôi là các phương thức bắt đầu bằng _) được sử dụng ở một vài nơi trong lớp là những ứng cử viên tốt, chẳng hạn. Mặt khác, các phương thức được sử dụng bởi hàng tá các lớp trên cơ sở mã là các ứng cử viên rất xấu.

Rốt cuộc, không nên mất quá nhiều nỗ lực để viết lại các đối số của một phương thức bạn gọi trong phương thức bạn viết. Hy vọng rằng, hầu hết các phương thức không mất hơn sáu đến tám đối số và nếu có, hãy tự hỏi liệu bạn có nên tái cấu trúc mã không. Trong tất cả trường hợp:

  • Làm cho các đối số rõ ràng trong phương thức của bạn không đòi hỏi nhiều nỗ lực,

  • Sau này, bạn có thể muốn xác thực các đối số (mặc dù nếu bạn chỉ dựa vào điểm này để làm cho các đối số rõ ràng, bạn đã vi phạm YAGNI).


Tôi thực sự thích câu trả lời này và nghĩ rằng đây là một câu hỏi hay. Thật không may, rất nhiều mã của chúng tôi có rất nhiều phương thức công khai sử dụng mẫu này. Nhưng bây giờ tôi có lập luận rằng chúng ta nên thay đổi nó (và bỏ matplotlib, không bao giờ thấy một "giao diện" crappier ..)
Christian Sauer

3

Nếu hàm cấp tiếp theo có __doc__, thì bạn có thể sao chép __doc__ sang hàm mới.

Ví dụ:

def a(x):
    """This function takes one parameter, x, and does nothing with it!"""
    pass

def b(**kwargs):
    a(**kwargs)

b.__doc__=a.__doc__

Điều này có thể áp dụng đệ quy và có thể được áp dụng bởi một người trang trí (có thể hữu ích nếu bạn đang làm điều này với số lượng lớn). Chuỗi __doc__ cũng có thể được thao tác để thêm nhiều hơn vào cuối. Điều này có nghĩa là các tham số hiển thị vẫn sẽ là kwargs, nhưng ít nhất có tài liệu hướng dẫn mô tả các tham số thực tế.

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.