Làm thế nào tôi nên đặt tên hàm trả về giá trị trong Python?


13

Tôi bối rối về việc chọn tên cho các chức năng của mình trong Python . Đôi khi các hàm dựng sẵn của Pythonbắt buộc, chẳng hạn như: printhàm và phương thức chuỗi find. Đôi khi, họ không phải là: chẳng hạn như lentên của nó, chẳng hạn như calculate_len, và typekhông find_type.

Tôi có thể hiểu rằng printtrả về một giá trị mà chúng ta không sử dụng (nghĩa là None) và thực hiện một cái gì đó (tức là nó hiển thị một chuỗi trên màn hình), vì vậy tên của nó là bắt buộc.

Nhưng lentrả về một giá trị mà chúng ta sử dụng và thực hiện một cái gì đó (nghĩa là tính toán có bao nhiêu mục trong một chuỗi hoặc ánh xạ.) Và tên của nó không bắt buộc . Mặt khác, findphương thức chuỗi (as len) trả về một giá trị mà chúng ta sử dụng và thực hiện một cái gì đó, và tên của nó là bắt buộc .

Điều khiến cho câu hỏi này là tôi đặt một tập lệnh mã hóa và giải mã chuỗi bằng mật mã Caesar để được xem xét. Người đánh giá nói rằng:

Chỉ là một cảm giác ruột: chức năng làm công cụ. Vì vậy, một tên tốt cho một chức năng là một mệnh lệnh: Tôi sẽ sử dụng rotate_letterthay vì rotated_letter.

rotated_lettertrả về một chuỗi ký tự đơn đại diện cho một chữ cái được quay bởi một số. Tôi không biết cái gì tốt hơn, tôi đã sử dụng rotated_lettervì nó trả về một giá trị, như randinthàm trong mô-đun ngẫu nhiên , không phải vậy generate_randint.

Vì vậy, trong trường hợp này, tôi nên đặt tên cho hàm trả về giá trị sẽ được sử dụng như thế nào? Tôi nên làm cho tên bắt buộc hoặc chỉ là một danh từ . Trong các trường hợp khác, rõ ràng là làm thế nào để làm điều đó, chẳng hạn như các hàm boolean , chẳng hạn như is_evenis_palindromechúng ta chỉ làm cho nó giống như một câu hỏi có / không , và cả các hàm chỉ làm và trả về các giá trị không sử dụng (ví dụ None), như printphương thức liệt kê sort.


đó thực sự là một cách làm rất phổ biến (tôi muốn nói là một quy ước) để sử dụng các mệnh lệnh khi đặt tên hàm. Chẳng hạn, làm thế nào để bạn đặt tên cho một biến lưu trữ chữ cái xoay của hàm rotated_letter?
JoulinRouge

Đó không phải là một cách nghĩ tốt về một số ví dụ của bạn. len, ví dụ, được coi là "độ dài" tốt hơn - bạn đang nhận được một mô tả siêu cấp về đối số của nó.
Izkata

Câu trả lời:


10

Sử dụng động từ ở nơi hợp lý, danh từ nếu chúng ngắn hơn và không rõ ràng

Hầu hết thời gian, các hàm nên là động từ (mệnh lệnh) và các lớp, biến và tham số nên là danh từ. Các thuộc tính cũng phải là danh từ, bao gồm cả những thuộc tính được tạo bằng cách sử dụng @property. Điều này đặc biệt là trường hợp cho các chức năng có tác dụng phụ. [1] Nếu một hàm trả về một cái gì đó, bạn nên đánh giá xem động từ có thêm thứ gì đó hay chỉ là "tiếng ồn":

  • make_list(foo)vs list(foo).: Danh từ dễ đọc hơn động từ. Ngoài ra, listthực sự là một lớp, và các lớp nên là danh từ.
  • open(foo)vs file(foo).: Động từ dễ đọc hơn danh từ và việc đưa ra "tùy chọn" cho động từ sẽ hợp lý hơn so với danh từ, vì vậy danh từ đã bị xóa trong Python 3. open()vẫn là cách "chuẩn" duy nhất [2] để tạo các đối tượng tệp trong Python 3.
  • foo.get_bar()vs. foo.bar()vs. foo.bar(giả sử foobarlà cả hai danh từ): Tùy chọn đầu tiên là đúng, bởi vì "get" không thêm bất cứ điều gì mà chúng ta chưa biết. Thứ hai là thích hợp nếu barthoát khỏi một foohoạt động có khả năng tốn kém và / hoặc mang các tác dụng phụ (bạn cũng có thể xem xét Bar(foo)nếu Barlà một lớp học). Thứ ba là phù hợp nếu đây là một hoạt động giá rẻ không có tác dụng phụ, và việc triển khai thay thế không có khả năng làm cho nó đắt tiền .
  • xs.sort()vs. sorted(xs)if xsis a list: Đầu tiên là bắt buộc: Sắp xếp danh sách. Nó sửa đổi danh sách tại chỗ và không trả về gì cả. Thứ hai là khai báo: Một danh sách được sắp xếp, đó chính xác là những gì nó trả về. Cả hai đều là động từ.

[1]: Thường trả về một giá trị và có tác dụng phụ là loại trừ lẫn nhau trừ khi bạn có một số lý do thiết kế hấp dẫn để kết hợp chúng. Vì vậy, một chức năng có tác dụng phụ có lẽ sẽ không trả lại bất cứ điều gì và do đó làm cho nó trở thành một danh từ sẽ rất ít ý nghĩa.
[2]: Có một số hoạt động ở mức độ thấp hơn vừa phải trong iomô-đun có thể được sử dụng để thêm hoặc xóa bộ đệm tệp, en / giải mã văn bản tự động, v.v., và đây chủ yếu là các danh từ vì chúng là các lớp hướng đối tượng. Hầu hết người dùng không cần phải chơi trực tiếp với những thứ này; thay vào đó, open()chọn một lớp thích hợp và tự động khởi tạo nó.


Cảm ơn bạn! Trong " foo.get_bar() vs.` foo.bar ()` vs. foo.bar" sự khác biệt giữa thứ haithứ ba là gì?
Mahmood Muhammad Nageeb

Thứ ba là một thuộc tính hoặc thuộc tính trần. Thứ hai là một phương pháp.
Kevin

Vì vậy, nếu tôi hiểu, thật phù hợp để không rotated_letterbắt buộc và giữ nó tuyên bố, phải không?
Mahmood Muhammad Nageeb

Trong trường hợp này, tôi không chắc liệu có letterđược ngụ ý bởi bối cảnh hay không.
Kevin

+1 để đề cập listlà một lớp học
Dušan Maďar

0

rotated_letterkhông giống như một phương pháp. Nó trông giống như một tài sản. Điều đó có nghĩa là ý tưởng đầu tiên là thực hiện:

var letter = caesar.rotated_letter

mong muốn letterchứa một giá trị của chuỗi kiểu, không phải là hàm. Từ đó, hoặc bạn chọn một tên khác, chẳng hạn như:

def rotate_letter(self):
    pass

hoặc bạn sử dụng một tài sản thay thế:

@property
def rotated_letter(self):
    return self.whatever

lentypeđược đặt tên như vậy bởi vì bất kỳ tên nào khác sẽ dài để gõ. Chúng được sử dụng rất nhiều và chúng có trạng thái đặc biệt là các hàm Python lõi mà mọi lập trình viên Python sẽ học dù sao, làm cho tên của chúng không liên quan hơn nhiều so với tên của các thư viện bên thứ ba.

len, đặc biệt, là một ví dụ tốt về những gì bạn không nên làm trong mã của mình : bạn sẽ sử dụng tên đầy đủ như length(trừ khi hình thức ngắn rất phổ biến, chẳng hạn như max) và sử dụng động từ, chẳng hạn như compute_length. Hoặc nó có thể là một tài sản: len([1, 5, 6])trở thành [1, 5, 6].length. Ví dụ, trong C #, hình thức sau được sử dụng : new [] { ... }.Length.

Lưu ý rằng có thể có các lý do lịch sử đối với len: các ngôn ngữ khác, chẳng hạn như C #, được ưa thích Count, thường là một phương thức (mặc dù hành vi không may không nhất quán thông qua .NET Framework). Countlà một động từ, do đó bằng trực giác, bạn có xu hướng gọi nó như một phương thức.

Trả lại giá trị hoặc thực hiện một hành động

Một chức năng luôn được mong đợi để thực hiện một hành động. Nếu nó hầu như không trả về một giá trị, nó sẽ là một tài sản. Bạn có một gợi ý rằng hàm nên được chuyển thành thuộc tính khi:

  • Hàm hầu như không chứa một return ...câu lệnh,

  • Tên của hàm xuất hiện tự nhiên trong tâm trí của bạn get_something, như trong product.get_price().

Bây giờ, nếu bạn có một chức năng, nó có thể là một trong bốn loại:

  • Nó có thể là thuần túy, đó là trả lại một giá trị mà không ảnh hưởng đến môi trường. Ví dụ : road.measure_distance().

  • Nó có thể ảnh hưởng đến môi trường mà không trả lại bất cứ điều gì. Ví dụ : product_database.remove_record(1234).

  • Nó có thể ảnh hưởng đến môi trường và trả về một giá trị. Ví dụ: value.increment()được sử dụng như value++.

  • Nó không thể làm gì và trả lại không có gì. Ví dụ : time.sleep(1).

Có một vài trường hợp tên có thể đưa ra gợi ý mạnh mẽ về loại hàm, nhưng trong nhiều trường hợp, bạn sẽ không thể biết loại này chỉ từ tên của nó.


Tôi giả sử câu trả lời là "có", nhưng tôi phải hỏi: bạn có trả lời hoàn toàn từ quan điểm của Python không? Bởi vì trong các ngôn ngữ khác, việc phân tách chức năng và thuộc tính của bạn không phải lúc nào cũng đúng; cũng không đúng khi một chức năng "phải thực hiện một hành động". Đây có phải là quy ước trong Python? (Tôi viết Python nhưng chưa đọc tất cả các PEP và tôi chắc chắn KHÔNG phải là chuyên gia. Tôi không downvote, BTW).
Andres F.

@AndresF.: Tôi đang trả lời từ quan điểm của Python. Trong các ngôn ngữ như Java nơi các thuộc tính không tồn tại getSomethingsetSomethinglà các tên thông thường được sử dụng thay cho các thuộc tính.
Arseni Mourzenko
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.