2012-03-12 11 views
6

Ho un programma che sto scrivendo in Python che effettua le seguenti operazioni:I metodi verbose __init__ in Python sono errati?

L'utente inserisce il nome di una cartella. All'interno di questa cartella sono presenti 8-15 file .dat con diverse estensioni.

Il programma apre quei file dat, li inserisce in un database SQL e consente all'utente di selezionare diverse modifiche apportate al database. Quindi il database viene esportato nei file .dat. Ci sono circa 5-10 diverse operazioni che potrebbero essere eseguite.

Il modo in cui avevo pianificato di progettare questo era creare una classe standard per ogni gruppo di file. L'utente dovrebbe inserire il nome della cartella e un oggetto con determinati attributi (nomi di file, dizionario di file, versione di file (ci sono diverse versioni), ecc). Determinare questi attributi richiede l'apertura di alcuni di questi file, la lettura di nomi di file, ecc.

Questa azione deve essere eseguita nel metodo __init__? O questa azione dovrebbe essere svolta in diversi metodi di istanza che vengono richiamati nel metodo __init__? O questi metodi dovrebbero essere da qualche altra parte, e devono essere chiamati solo quando l'attributo è richiesto altrove nel programma?

Ho già scritto questo programma in Java. E avevo un costruttore che chiamava altri metodi nella classe per impostare gli attributi dell'oggetto. Ma mi stavo chiedendo quale sarebbe la pratica standard in Python.

risposta

1

Sembra che l'azione che si sta descrivendo sia l'inizializzazione, quindi sarebbe perfettamente ok inserirli in __init__. D'altra parte, queste azioni sembrano essere piuttosto costose e probabilmente utili nell'altra parte di un programma, quindi potresti volerle incapsulare in una funzione separata.

1

Il metodo __init__ viene chiamato quando l'oggetto viene istanziato.

Provenendo da uno sfondo C++, ritengo che non sia corretto eseguire lavori diversi dall'inizializzazione nel costruttore.

1

Non c'è alcun problema con un lungo metodo __init__, ma lo eviterei semplicemente perché è più difficile da testare. Il mio approccio sarebbe quello di creare metodi più piccoli che vengono chiamati da __init__. In questo modo puoi testarli separatamente e l'inizializzazione.

Se debbano essere richiamati quando necessario o funzionare in anticipo dipende davvero da ciò che è necessario che facciano. Se sono operazioni costose e di solito non sono tutte necessarie, allora forse è meglio chiamarle solo quando necessario. D'altra parte, potresti voler eseguirli in anticipo in modo che non ci sia lag quando gli attributi sono richiesti.

Non è chiaro dalla tua domanda se hai effettivamente bisogno di una lezione. Non ho esperienza con Java, ma capisco che tutto ciò che contiene è una classe. In Python è perfettamente accettabile avere una funzione solo se è tutto ciò che è necessario, e solo creare classi quando hai bisogno di istanze e altre cose di classe.

+0

Essenzialmente ho un gruppo di file che possono essere classificati come "lavoro". Diverse funzioni eseguono diverse azioni su questo lavoro per produrre il risultato desiderato del programma. Questo è il motivo per cui ho pensato che fosse meglio tenerlo come classe. –

+0

E sembra che questo è quello che stai suggerendo: __init __ (self, nomecartella): self.filelist = getfilelist (...); self.fileversion = getfileversion (...); ecc.? Tranne nell'istanza che uno dei metodi è costoso e necessario solo in determinati casi? –

+0

Se questo è ciò che fa il tuo codice, allora forse dovresti usare [proprietà pigri] (http://stackoverflow.com/q/3012421/1235039). Ci sono molti modi per farlo, dipende solo dalle tue esigenze e preferenze. – aquavitae

3

Bene, non c'è nulla di speciale nelle buone pratiche OOP in Python. La scomposizione di un grande metodo in un gruppo di piccoli è una grande idea sia in Java che in Python.Tra le altre cose piccole metodi ti dà l'opportunità di scrivere diversi costruttori:

class GroupDescriptor(object): 
    def __init__(self, file_dictionary): 
     self.file_dict = file_dictionary 
     self.load_something(self.file_dict['file_with_some_info']) 

    @classmethod 
    def from_filelist(cls, list_of_files): 
     file_dict = cls.get_file_dict(list_of_files) 
     return cls(file_dict) 

    @classmethod 
    def from_dirpath(cls, directory_path): 
     files = self.list_dir(directory_path) 
     return cls.from_filelist(files) 

Inoltre, non so come sia in Java, ma in Python non dovete preoccuparvi di eccezioni nel costruttore, perché sono finemente gestito. Pertanto, è del tutto normale lavorare con cose così inclini come i file.

+0

+1 La migliore risposta finora! ;-) Adoro le insinuazioni della decomposizione con il costruttore/inizializzatore "polimorfico" che termina-sposta anche se è leggermente sciatto, perché non lo hai elaborato! –