2013-05-16 11 views
5

Dlaczego funkcje powinny być zadeklarowane poza klasą, z której korzystają w Pythonie?Co jest zaletą zdefiniowania jakiejś funkcji poza klasą w pythonowym programie?

Na przykład following project on Github wykonuje to za pomocą funkcji _hash, _task_from_taskline i . Format jest taki sam, jak poniżej:

class UnknownPrefix(Exception): 
"""Raised when trying to use a prefix that does not match any tasks.""" 
def __init__(self, prefix): 
    super(UnknownPrefix, self).__init__() 
    self.prefix = prefix 


def _hash(text): 

    return hashlib.sha1(text).hexdigest() 

def _task_from_taskline(taskline): 
    """ 
    snipped out actual code 
    """ 
    return task 

def _tasklines_from_tasks(tasks): 
    """Parse a list of tasks into tasklines suitable for writing.""" 


    return tasklines 

Ale myślę, że funkcje te mają związek z klasy TaskDict.

Po co je wyrzucać z klasy? Jaka jest przewaga posiadania ich zadeklarowanych poza klasą?

+1

obróć ją: Co zaletą byłoby umieścić je w klasie zamiast? –

+0

@MartijnPieters Encapsulation. –

+0

@GeorgeStocker: co jeśli funkcje nie mają wpływu na stan instancji? –

Odpowiedz

3

Stop Writing Classes PyCon rozmowa nie jest dokładnie na ten temat, ale zawiera co czuję związane są lekcje tutaj: Zasadniczo chodzi o to, że zajęcia są do tworzenia obiektów. Wszystkie atrybuty, metody instancji i metody klasy powinny dodatkowo tworzyć obiekty lub sprawiać, by obiekty działały. Klasy nie służą do organizacji kodu (w tej teorii) - do tego służą moduły.

To jest bardzo popularna strategia i nie wszyscy się z nią zgadzają. Ale jeśli pomyślisz o swoim przykładzie w tym kontekście, jasne jest, że powodem, dla którego funkcje nie są częścią klasy, jest to, że pomimo tego, że funkcje są używane przez klasę, nie działają one na żadnym obiekcie ani na dalszym etapie tworzenia. dowolnego obiektu bezpośrednio. Są to tylko funkcje narzędziowe, które nie są związane z żadną konkretną klasą i teoretycznie mogłyby być używane w innych miejscach biblioteki.

Dlaczego i dlaczego nie umieścić ich w klasie? Sprowadza się to do tego, czy uważasz, że klasy powinny być używane do organizacji kodu, czy nie. W tym przypadku autor najwyraźniej nabrał przekonania, że ​​chodzi o moduły służące do organizacji kodu, a nie do klas.

0

Zwykle przy podejmowaniu decyzji, gdzie umieścić funkcje, ważne jest, aby rozpoznać, jakie funkcje będą używane. Jeśli są one wewnętrzną częścią klasy i nie będą używane przez inne części twojego programu, warto umieścić je w klasie. Ale jeśli inne części najprawdopodobniej z nich skorzystają, powinny znajdować się na poziomie modułu.

+0

Tak, myślałem, że, myślę, że funkcje należą do klasy i nie będą używane dla innych z klasy. Tak więc wątpię, aby zdefiniować poza klasą – poleworld

1

Jeśli wszystkie zdefiniowane funkcje działają na danych w obiekcie, sensowne byłoby tylko enkapsulowanie funkcji na poziomie klasy. Ponadto, widząc, jak klasa jest jedyną rzeczą wywołującą te funkcje, byłoby sensowne umieszczenie ich w klasie.

Jedyną zaletą umieszczenia ich poza klasą jest, jeśli masz inny kod, który będzie korzystać z tych funkcji, które nie są związane z samą klasą. Lub jeśli budujesz pewne funkcje pomocnicze, które będą używane przez inne moduły.

3
  1. Są one łatwiejsze do importu i mają krótszą nazwę niż funkcji składowych
  2. Nawet jeśli umieścić je w klasie, są one prawdopodobnie będzie classmethod/staticmethod tak.
  3. Kod pythonowy wykorzystuje pisanie kaczkami; metoda oznaczałaby, że może być używana tylko z tą klasą, podczas gdy w rzeczywistości kod może być bardziej ogólny.
  4. Osobiste preferencje. Niektórzy lubili oddzielać "model domeny" od "logiki biznesowej".

Podsumowując, w przypadku tego konkretnego programu nie ma naprawdę żadnych korzyści ani niekorzyść dla robienia tego w obu kierunkach.

+0

Tak, dla mnie. Umieszczę je w klasie i zdefiniuję jako metodę statyczną. – poleworld

1

funkcje ma małe przewagę wydajności

>>> import timeit 
>>> timeit.Timer('foo()', 'def foo(): return 1').timeit() 
0.09944701194763184 
>>> timeit.Timer('A.foo()', ''' 
... class A(object): 
...  @staticmethod 
...  def foo(): 
...   return 1''').timeit() 
0.12048101425170898 
Powiązane problemy