2013-05-16 25 views
5

Perché le funzioni dovrebbero essere dichiarate al di fuori della classe in cui sono utilizzate in Python?Qual è il vantaggio di definire alcune funzioni fuori classe nel programma python

Ad esempio, lo following project on Github esegue questa operazione con le sue funzioni , _task_from_taskline e _tasklines_from_tasks. Il formato è lo stesso come il seguente:

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 

Ma credo che queste funzioni hanno un rapporto con la classe TaskDict.

Perché metterli fuori dalla classe? Qual è il vantaggio di averli dichiarati al di fuori della classe?

+1

girare intorno: Quale sarebbe il vantaggio è quello di metterli nella classe, invece? –

+0

@MartijnPieters Incapsulamento. –

+0

@GeorgeStocker: cosa succede se le funzioni non hanno alcun rapporto con lo stato dell'istanza? –

risposta

3

Il Stop Writing Classes PyCon discorso non è esattamente su questo argomento, ma comprende ciò che mi sembrano imparentato lezioni qui: in sostanza, l'idea è che classi sono per la creazione di oggetti. Tutti gli attributi, i metodi di istanza e i metodi di classe dovrebbero favorire l'obiettivo di creare oggetti o far funzionare gli oggetti. Le classi non sono per l'organizzazione del codice (sotto questa teoria) - questo è ciò che i moduli servono.

Questa è una strategia molto opinata e non tutti sono d'accordo. Ma se pensi al tuo esempio in questo contesto, è chiaro che la ragione per cui le funzioni non fanno parte della classe è che anche se le funzioni sono utilizzate dalla classe, in effetti non operano su alcun oggetto o sulla creazione di qualsiasi oggetto direttamente. Sono solo funzioni di utilità che non sono associate a una classe specifica e potrebbero teoricamente essere utilizzate altrove nella libreria.

Quindi perché o perché non metterli in classe? Si riduce a se si ritiene che le classi dovrebbero essere utilizzate per l'organizzazione del codice o meno. In questo caso, l'autore ha apparentemente acquistato l'idea che si tratta di moduli che sono per l'organizzazione del codice, non le classi.

0

In genere, quando si decide dove posizionare le funzioni è importante riconoscere le funzioni che verranno utilizzate. Se sono interni alla classe e non saranno usati da altre parti del tuo programma, ha senso inserirli nella classe. Ma se altre parti probabilmente le useranno, dovrebbero essere a livello di modulo.

+0

sì, ho pensato che, penso che le funzioni appartengano alla classe, e non saranno usate da altri fuori dalla classe. Quindi dubito del perché definire in classe – poleworld

1

Se le funzioni definite operano tutte sui dati all'interno dell'oggetto, avrebbe senso solo incapsulare le funzioni a livello di classe. Inoltre, vedere come la classe è l'unica cosa che chiama quelle funzioni, avrebbe senso metterle in classe.

L'unico vantaggio di metterli al di fuori della classe è se si dispone di un altro codice che utilizzerà queste funzioni non correlate alla classe stessa. O se stai costruendo alcune funzioni di supporto che saranno utilizzate da altri moduli.

3
  1. Sono più facili da importare ed avere nome più breve di funzioni membro
  2. Anche se li metti nella classe, sono probabilmente sarà un classmethod/staticmethod comunque.
  3. Il codice Pythonic utilizza la digitazione anatra; un metodo implicherebbe che possa essere usato solo con quella classe, mentre in realtà il codice potrebbe essere più generico di quello.
  4. Preferenza personale. Ad alcune persone piaceva separare il "modello di dominio" e la "logica aziendale".

Alla fine, per questo particolare programma, non c'è davvero alcun vantaggio né svantaggio per fare entrambe le cose.

+0

Sì, per me. Li inserirò nella classe e definirò il metodo statico. – poleworld

1

funzioni ha piccolo vantaggio di prestazioni

>>> 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 
Problemi correlati