Il modo migliore per archiviare e utilizzare un grande file di testo in Python

StackOverflow https://stackoverflow.com/questions/158546

  •  03-07-2019
  •  | 
  •  

Domanda

Sto creando un server in rete per un clone di boggle che ho scritto in Python, che accetta gli utenti, risolve le schede e segna l'input del giocatore. Il file del dizionario che sto usando è 1,8 MB (il dizionario ENABLE2K) e ho bisogno che sia disponibile per diverse classi di risolutore di giochi. In questo momento, ce l'ho in modo che ogni classe esegua l'iterazione del file riga per riga e generi una tabella hash (array associativo), ma più classi di risolutore ho istanza, più memoria occupa.

Quello che vorrei fare è importare il file del dizionario una volta e passarlo a ogni istanza del risolutore quando ne hanno bisogno. Ma qual è il modo migliore per farlo? Devo importare il dizionario nello spazio globale, quindi accedervi nella classe del solutore come globals () ['dizionario']? O dovrei importare il dizionario e poi passarlo come argomento al costruttore della classe? Uno di questi è migliore dell'altro? C'è una terza opzione?

È stato utile?

Soluzione

Se si crea un modulo Dictionary.py, contenente il codice che legge il file e crea un dizionario, questo codice verrà eseguito solo la prima volta che viene importato. Ulteriori importazioni restituiranno un riferimento all'istanza del modulo esistente. Pertanto, le tue lezioni possono:

import dictionary

dictionary.words[whatever]

dove dizionario.py ha:

words = {}

# read file and add to 'words'

Altri suggerimenti

Anche se è essenzialmente un singleton a questo punto, si applicano i soliti argomenti contro i globali. Per un sostituto singleton pitone, cerca il " borg " oggetto.

Questa è davvero l'unica differenza. Una volta creato l'oggetto dizionario, si vincolano solo nuovi riferimenti mentre lo si passa a meno che non si esegua esplicitamente una copia profonda. Ha senso che sia costruito centralmente una volta e una sola volta, purché ogni istanza del solutore non richieda una copia privata per la modifica.

Adam, ricordalo in Python quando dici:

a = read_dict_from_file()
b = a

... in realtà non stai copiando a , e quindi usando più memoria, stai semplicemente facendo b un altro riferimento allo stesso oggetto.

Quindi sostanzialmente qualsiasi delle soluzioni che proporrete sarà molto meglio in termini di utilizzo della memoria. Fondamentalmente, leggi nel dizionario una volta e poi aggrappati a un riferimento a quello. Che tu lo faccia con una variabile globale, o lo passi a ciascuna istanza o qualcos'altro, farai riferimento allo stesso oggetto e non lo duplicherai.

Qual è il più Pythonic? Questa è un'intera lattina di worm, ma ecco cosa farei personalmente:

def main(args):
  run_initialization_stuff()
  dictionary = read_dictionary_from_file()
  solvers = [ Solver(class=x, dictionary=dictionary) for x in len(number_of_solvers) ]

HTH.

A seconda di cosa contiene il tuo dict, potresti essere interessato ai moduli 'shelve' o 'anydbm'. Ti danno interfacce simili a dict (solo stringhe come chiavi ed elementi per 'anydbm', e stringhe come chiavi e qualsiasi oggetto python come elemento per 'shelve') ma i dati sono in realtà in un file DBM (gdbm, ndbm, dbhash, bsddb, a seconda di ciò che è disponibile sulla piattaforma.) Probabilmente vorrai ancora condividere il database effettivo tra le classi come stai chiedendo, ma eviterebbe il passaggio di analisi del file di testo e il mantenimento del tutto in -memory bit.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top