2013-10-27 13 views
16

Mam plik, który miał być plikiem użytkowym. Plik powinien zawierać wiele statycznych metod.Jak poprawnie utworzyć klasę narzędzia?

Czy mogę zdefiniować metody wewnątrz klasy w ten sposób:

#utility.py 
class utility(object): 
    @staticmethods 
    def method1(a,b,c): 
     pass 

    @staticmethods 
    def method2(a,b,c): 
     pass 

lub używać go tak (bez klasy):

#utility.py 
def method1(a,b,c): 
    pass 

def method2(a,b,c): 
    pass 
+6

Funkcje są lepiej zdefiniowane jako funkcje. Jeśli nie potrzebujesz lekcji, nie rób tego. –

+0

Oto odpowiedź, której szukałem: P – Nirock

+2

@PaulGriffiths dokładnie. @Nirock Silnym wskaźnikiem, że metoda może/powinna być funkcją, jest to, że nie używa ona argumentu "self". Narzędzia takie jak ['pylint'] (http://www.pylint.org/) nawet sprawdzają to i dają wskazówkę. –

Odpowiedz

19

Druga opcja jest modus operandi w Pythonie. Mam na myśli to, że jeśli wszystko, co robisz, importuje funkcje, możesz zrobić coś takiego:

from utility import some_func 

, który zaimportuje twoją funkcję.

Najlepszą praktyką jest używanie wyłącznie funkcji statycznych, a następnie umieszczanie ich w globalnym obszarze nazw oddzielnego modułu, co znacznie ułatwi Ci życie. Próbujesz tworzyć obiekty i wypełniaj je statycznymi metodami. Dlaczego tak jest, kiedy można po prostu zdefiniować funkcje w pliku .py?

To, co próbujesz zrobić, to . Zostało wykonane. Próbujesz przechowywać dobre funkcje narzędziowe. Cóż, python-requests, to trzecia biblioteka, która jest po prostu uwielbiana przez większość Pythonistas właśnie to robi. Przechowuje swoje dobre funkcje użytkowe w osobnym module. Here is the example.

+0

Czuję się bardziej komfortowo, aby używać go z narzędziem utility.method1 (...). Czy powinienem zmusić się do zrobienia tego w ten sposób? Naprawdę chcę skorzystać z najlepszej praktyki. – Nirock

+0

** NIGDY ** użyj 'from foo import *' w kodzie produkcyjnym. Uniemożliwia śledzenie pochodzenia importu i może przyćmić wbudowane nazwy. –

+2

Najlepszą praktyką jest, jeśli używasz tylko funkcji statycznych, a następnie umieść je w globalnym obszarze nazw oddzielnego modułu, ułatwi to Ci życie. –

7

Podczas gdy to pytanie jest trochę oparte na opiniach, powiedziałbym, że drugi jest lepszy. Zmniejsza redundancję. Korzystanie z pierwszej metody, trzeba będzie zrobić:

import utility 
utility.utility.method1(...) 

czyli

from utility import utility 
utility.method1(...) 

stosując jednak druga pozwala po prostu zrobić:

import utility 
utility.method1(...) 

lub:

from utility import method1 
method1(...) 

Jeśli tworzysz zajęcia, które na ly zawiera statyczne metody, moje pytanie brzmi "dlaczego potrzebujesz klasy?" Nie ma w tym nic pozytywnego.

9

Klasy hermetyzacji zarówno dane i zachowanie, tak ogólnych zasad:

  • Jeśli masz coś tylko z danymi, i żadne metody, powinny prawdopodobnie być namedtuple, a nie class, chyba że trzeba zmodyfikuj dane po ich utworzeniu.
  • Jeśli funkcja uzyskuje dostęp do danych instancji, powinna to być metoda.
  • Jeśli funkcja nie uzyskuje dostępu do danych instancji, ale ma dostęp do danych klasy, powinna to być nazwa @classmethod.
  • Jeśli funkcja nie uzyskuje dostępu ani do danych instancji, ani do danych klas, powinna być samodzielną funkcją, chyba że jest jakiś naprawdę ważny powód, aby uczynić ją numerem @staticmethod.
  • Jeśli tylko class ma jedną metodę lub jedną metodę oprócz __init__(), to prawie na pewno można i powinno się przepisać ją jako funkcję.

Klasy są naprawdę łatwe do nadużywania, ale należy unikać pokusy popchnięcia wszystkiego do klasy. Powinieneś ich używać, gdy mają sens, i unikać używania ich, gdy tego nie robią.

+0

Dobra kompleksowa odpowiedź. –

Powiązane problemy