Nie jestem pewien, czy wybieram nazwy dla moich funkcji w Pythonie . Czasami niezbędne są funkcje wbudowane w Python , takie jak: print
funkcja i metoda łańcuchowa find
. Czasami nie są tacy, jak: len
jego nazwa nie jest niezbędna, jak calculate_len
na przykład i type
nie jest find_type
.
Rozumiem, że print
zwraca wartość, której nie używamy (tj. None
) I robi coś (tj. Pokazuje ciąg znaków na ekranie), więc jej nazwa jest bezwzględna.
Ale len
zwraca wartość, że używamy i robi coś (czyli obliczenie ile przedmiotów istnieją w sekwencji lub mapowania.), A jego nazwa nie jest konieczne . Z drugiej strony find
metoda string (as len
) zwraca wartość, której używamy i robi coś, a jej nazwa jest bezwzględna .
To, co sprawiło, że zadałem to pytanie, polega na tym, że poddałem przeglądowi skrypt, który szyfruje i odszyfrowuje ciąg przy użyciu szyfru Cezara. Recenzent powiedział, że:
Po prostu przeczucie: funkcje robią różne rzeczy. Dobra nazwa funkcji jest więc niezbędna: użyłbym
rotate_letter
zamiastrotated_letter
.
rotated_letter
zwraca ciąg jednoliterowy reprezentujący literę obróconą o liczbę. Nie wiem, co jest lepsze, użyłem, rotated_letter
ponieważ zwraca wartość, jak randint
funkcja w module losowym , nie jest generate_randint
.
Więc w takim przypadku, jak mam nazwać funkcję, która zwraca wartość, która ma być użyta? Powinienem uczynić nazwę imperatywną, czy tylko rzeczownikiem . W innych przypadkach jest oczywiste, jak to zrobić, takie jak funkcje boolowskie , takie jak is_even
i is_palindrome
po prostu sprawiamy, że jest to pytanie typu tak / nie , a także funkcje, które tylko wykonują i zwracają nieużywane wartości (tj. None
), Takie jak print
i metoda list sort
.
źródło
len
, na przykład, lepiej jest traktować go jako „długość” - otrzymujesz opis jego argumentu na poziomie meta.Odpowiedzi:
Używaj czasowników tam, gdzie jest to uzasadnione, rzeczowników, jeśli są one krótsze i jednoznaczne
Przez większość czasu funkcjami powinny być (imperatywne) czasowniki, a klasy, zmienne i parametry powinny być rzeczownikami. Atrybutami powinny być także rzeczowniki, w tym te utworzone przy użyciu
@property
. Dotyczy to zwłaszcza funkcji wywołujących skutki uboczne. [1] Jeśli funkcja coś zwraca, powinieneś ocenić, czy czasownik coś dodaje, czy jest po prostu „szumem”:make_list(foo)
vslist(foo)
.: Rzeczownik jest łatwiejszy do odczytania niż czasownik. Poza tymlist
jest właściwie klasą, a klasy powinny być rzeczownikami.open(foo)
vsfile(foo)
.: Czasownik jest łatwiejszy do odczytania niż rzeczownik, i sensowniejsze jest dawanie „opcji” czasownikowi niż rzeczownikowi, więc rzeczownik został usunięty w Pythonie 3.open()
pozostaje jedynym „standardowym” [2] sposobem do tworzenia obiektów plików w Pythonie 3.foo.get_bar()
vsfoo.bar()
vsfoo.bar
(zakładamy,foo
ibar
to zarówno rzeczowniki): Pierwsza opcja jest prosto, bo „dostać” nie dodaje nic, że już nie wiem. Drugi jest odpowiedni, jeśli wydostaniebar
się zfoo
jest potencjalnie kosztowną operacją i / lub niesie ze sobą skutki uboczne (możesz również rozważyć,Bar(foo)
czyBar
jest to klasa). Trzeci jest odpowiedni, jeśli jest to tania operacja bez skutków ubocznych, a alternatywne wdrożenia raczej nie spowodują, że będzie kosztowna .xs.sort()
vs.sorted(xs)
ifxs
jest listą: pierwszy jest konieczny: posortuj listę. Zmienia listę w miejscu i nic nie zwraca. Drugi jest deklaratywny: lista jest posortowana, czyli dokładnie to, co zwraca. Oba są czasownikami.[1]: Zwykle zwracanie wartości i wywoływanie efektów ubocznych wykluczają się nawzajem, chyba że masz ważny powód, aby je połączyć. Tak więc funkcja, która ma skutki uboczne, prawdopodobnie nie powinna niczego zwracać, a zatem uczynienie z niej rzeczownika nie miałoby większego sensu.
[2]: W
io
module znajduje się kilka operacji na niższym poziomie , które można wykorzystać do dodawania lub usuwania buforowania plików, automatycznego en / dekodowania tekstu itp., I są to w większości rzeczowniki, ponieważ są to klasy obiektowe. Większość użytkowników nie musi bezpośrednio bawić się tymi rzeczami; zamiast tegoopen()
wybiera odpowiednią klasę i tworzy ją automatycznie.źródło
foo.get_bar()
vs.` foo.bar ()` vs.foo.bar
" jaka jest różnica między drugim a trzecim ?rotated_letter
nakazu i utrzymywać go w porządku, prawda?letter
wynika to z kontekstu.list
to klasarotated_letter
nie wygląda jak metoda. Wygląda jak własność. Co oznacza, że pierwszym pomysłem jest:oczekiwanie, że
letter
będzie zawierać wartość typu string, a nie funkcję. Następnie wybierz inną nazwę, na przykład:lub zamiast tego korzystasz z nieruchomości:
len
itype
są tak nazywane, ponieważ każda inna nazwa będzie długa do wpisania. Są często używane i mają specjalny status podstawowych funkcji Pythona, których i tak nauczy się każdy programista Pythona, przez co ich nazwy są znacznie bardziej nieistotne niż nazwy bibliotek stron trzecich.len
, Szczególnie, jest dobrym przykładem tego, co nie należy robić w swoim kodzie: jesteś oczekuje się używać pełnych nazw, takich jaklength
(chyba, że krótka forma jest bardzo popularne, takie jakmax
) i użyć czasownika, npcompute_length
. Lub może to być właściwość:len([1, 5, 6])
staje się[1, 5, 6].length
. Na przykład, w c #, później postać stosuje się:new [] { ... }.Length
.Należy pamiętać, że mogą istnieć również powody historyczne
len
: preferowane są inne języki, takie jak C #Count
, co zwykle jest metodą (chociaż zachowanie jest niestety niespójne w .NET Framework).Count
jest czasownikiem, więc intuicyjnie masz skłonność do inwokowania go jako metody.Zwracanie wartości lub wykonywanie akcji
Zawsze oczekuje się, że funkcja wykona akcję. Jeśli ledwo zwraca wartość, powinna być właściwością. Masz wskazówkę, że funkcję należy przekształcić we właściwość, gdy:
Funkcja ledwo zawiera
return ...
instrukcję,Nazwa funkcji, która naturalnie pojawia się w twoim umyśle, jest
get_something
jak wproduct.get_price()
.Teraz, jeśli masz funkcję, może to być jeden z czterech typów:
Może być czysty, to znaczy zwraca wartość bez wpływu na środowisko. Przykład:
road.measure_distance()
.Może wpływać na środowisko bez zwracania czegokolwiek. Przykład:
product_database.remove_record(1234)
.Może wpływać na środowisko i zwracać wartość. Przykład:
value.increment()
używane, takie jakvalue++
.Nic nie może zrobić i nic nie zwraca. Przykład:
time.sleep(1)
.Istnieje kilka przypadków, w których nazwa może dać silną wskazówkę na temat rodzaju funkcji, ale w wielu przypadkach nie będziesz w stanie poznać typu z jego nazwy.
źródło
getSomething
isetSomething
są to zwykłe nazwy używane zamiast właściwości.