English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Questo articolo risolverà passo dopo passo da diversi aspetti
1、La funzione principale del programma
2、Procedura di implementazione
3、Definizione della classe
4、Aggiornamento dinamico di ogni oggetto e restituzione dell'oggetto utilizzando generatori
5、Utilizzo di strip per rimuovere caratteri inutili
6、Matching di stringhe con rematch
7、Utilizzo di timestrptime per convertire una stringa in un oggetto di tempo
8、Codice completo
La funzione principale del programma
Adesso c'è un documento simile a una tabella per memorizzare informazioni degli utenti: la prima riga sono le proprietà, le proprietà sono separate da virgola (,), a partire dalla seconda riga, ogni riga rappresenta il valore di ogni proprietà, ogni riga rappresenta un utente. Come implementare la lettura di questo documento, per riga esportare un oggetto utente?
Inoltre ci sono altre 4 richieste specifiche:
Ogni documento è molto grande, se si memorizza tutti gli oggetti generati da tutte le righe in una lista in una volta, la memoria si romperà. Nel programma, ogni volta si può memorizzare solo un oggetto generato da una riga.
Ogni stringa separata da virgola, che può avere virgolette doppi (”) o singole ('), ad esempio ”张三”, deve rimuovere le virgolette; se è un numero, come +000000001.24, deve rimuovere il + e gli 0 iniziali e estrarre 1.24
Il documento contiene l'ora, che può essere nel formato 2013-10-29 o 2013/10/29 2:23:56. È necessario convertire queste stringhe in tipo data.
Ci sono molti documenti di questo tipo, ciascuno con attributi diversi, ad esempio questo è l'informazione dell'utente, quello è la cronologia delle chiamate. Pertanto, gli attributi specifici della classe devono essere generati dinamicamente in base alla prima riga del documento.
Procedura di implementazione
1. Definizione della classe
Poiché gli attributi vengono aggiunti dinamicamente, anche le coppie attributo-valore vengono aggiunte dinamicamente. Nella classe devono essere presenti due funzioni membri updateAttributes() e updatePairs(), oltre a utilizzare la lista attributes per memorizzare gli attributi e il dizionario attrilist per memorizzare le mappature. La funzione init() è il costruttore. I variabili di tipo __attributes hanno un trattino sottile davanti, indicando variabili private che non possono essere chiamate direttamente dall'esterno. L'istanziazione richiede solo a=a=UserInfo() senza alcun parametro.
class UserInfo(object): 'Classe per ripristinare le informazioni dell'utente' def __init__ (self): self.attrilist={} self.__attributes=[] def updateAttributes(self,attributes): self.__attributes=attributes def updatePairs(self,values): for i in range(len(values)): self.attrilist[self.__attributes[i]]=values[i]
2. Aggiornare dinamicamente ogni oggetto con il generatore (generator) e restituire l'oggetto
Un generatore è una funzione che deve essere inizializzata una volta sola e può essere eseguita automaticamente più volte, restituendo un risultato ogni ciclo. Tuttavia, la funzione restituisce i risultati con return, mentre il generatore li restituisce con yield. Ogni volta che viene eseguito, si ferma alla yield e la prossima volta inizia dopo la yield. Ad esempio, possiamo implementare la serie di Fibonacci utilizzando sia una funzione che un generatore:
def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a + b n = n + 1 return 'done'
Calcoliamo i primi 6 numeri della serie:
>>> fib(6) 1 1 2 3 5 8 'done'
Se si utilizza un generatore, è sufficiente sostituire print con yield. Esempio:
def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1
Modo d'uso:
>>> f = fib(6) >>> f <generator object fib at 0x104feaaa0> >>> for i in f: ... print(i) ... 1 1 2 3 5 8 >>>
Si può vedere che il generatore fib è un oggetto, ogni volta che si arriva a yield si interrompe e restituisce un risultato, poi continua a eseguire la riga di codice successiva a yield. Il generatore può anche essere eseguito con generator.next().
Nel mio codice del generatore, è così:
def ObjectGenerator(maxlinenum): filename='/home/thinkit/Documents/usr_info/USER.csv' attributes=[] linenum=1 a=UserInfo() file=open(filename) while linenum < maxlinenum: values=[] line=str.decode(file.readline(),'gb2312')#linecache.getline(filename, linenum,'gb2312') if line=='': print'reading fail! Please check filename!' break str_list=line.split(',') for item in str_list: item=item.strip() item=item.strip('\"') item=item.strip('\'') item=item.strip('+0*') item=catchTime(item) if linenum==1: attributes.append(item) else: values.append(item) if linenum==1: a.updateAttributes(attributes) else: a.updatePairs(values) yield a.attrilist #Change to ' a ' to use linenum = linenum +1
In questo caso, a=UserInfo() è un'istanza della classe UserInfo. Poiché il documento è codificato in gb2312, è stato utilizzato il metodo di decodifica corrispondente. Poiché la prima riga è un attributo, c'è una funzione che inserisce la lista degli attributi in UserInfo, ossia updateAttributes(); Le righe successive devono leggere il pair attributo-valore e inserirlo in un dizionario per memorizzarlo. p.s. Il dizionario in Python è equivalente a una mappatura (map).
3. Rimuovere i caratteri inutili utilizzando strip
Dalla codice sopra, si può vedere che utilizzare str.strip(somechar) è sufficiente per rimuovere i caratteri somechar all'inizio e alla fine di str. somechar può essere un simbolo, può anche essere un'espressione regolare, come sopra:
item=item.strip()#Rimuovere tutti i caratteri di escape all'inizio e alla fine della stringa, come \t, \n, ecc. item=item.strip('\"')#Rimuovere i caratteri " all'inizio e alla fine item=item.strip('\'') item=item.strip('+0*')#Rimuovere i caratteri +00...00 all'inizio e alla fine, * indica che il numero di 0 può essere qualsiasi numero, può anche non esserci
4. Match della stringa con re.match
Sintassi della funzione:
re.match(pattern, string, flags=0)
Descrizione dei parametri della funzione:
parametro Descrizione
pattern Espressione regolare da matchare
string Stringa da matchare.
flags Indice di segno, utilizzato per controllare il modo di match della espressione regolare, come: se distinguere tra maiuscole e minuscole, match multi-linea, ecc.
Se il match è successo, il metodo re.match restituisce un oggetto di match, altrimenti restituisce None.
>>> s='2015-09-18'
>>> matchObj=re.match(r'\d{4}-\d{2}-\d{2}',s, flags= 0)
>>> print matchObj
<_sre.SRE_Match oggetto at 0x7f3525480f38>
1
2
3
4
5
5. Estrarre una stringa in un oggetto di tempo utilizzando time.strptime
Nel modulo time, time.strptime(str, format) può trasformare str secondo il formato format in un oggetto di tempo, i formati comuni di format sono:
L'anno in formato a due cifre (%y) (00-99)
L'anno in formato a quattro cifre (%Y) (000-9999)
Il mese (%m) (01-12)
Il giorno del mese (%d) (0-31)
L'ora in formato 24 ore (%H) (0-23)
%I ora in formato 12 ore (01-12)
%M minuti (00-59)
%S secondi (00-59)
Inoltre, è necessario utilizzare il modulo re, utilizzando espressioni regolari, per abbinare le stringhe e vedere se è nel formato di tempo standard, come YYYY/MM/DD H:M:S, YYYY-MM-DD ecc.
Nel codice sopra, la funzione catchTime determina se item è un oggetto di tempo, se lo è, lo converte in un oggetto di tempo.
Il codice è il seguente:
import time import re def catchTime(item): # check if it's time matchObj=re.match(r'\d{4}-\d{2}-\d{2}',item, flags= 0) if matchObj!= None : item = time.strptime(item,'%Y-%m-%d') #print "returned time: %s " %item return item else: matchObj=re.match(r'\d{4}/\d{2}/\d{2}\s\d+:\d+:\d+',item,flags=0 ) if matchObj!= None : item = time.strptime(item,'%Y/%m/%d %H:%M:%S') #print "returned time: %s " %item return item
Codice completo:
import collections import time import re class UserInfo(object): 'Classe per ripristinare le informazioni dell'utente' def __init__ (self): self.attrilist=collections.OrderedDict()# ordered self.__attributes=[] def updateAttributes(self,attributes): self.__attributes=attributes def updatePairs(self,values): for i in range(len(values)): self.attrilist[self.__attributes[i]]=values[i] def catchTime(item): # check if it's time matchObj=re.match(r'\d{4}-\d{2}-\d{2}',item, flags= 0) if matchObj!= None : item = time.strptime(item,'%Y-%m-%d') #print "returned time: %s " %item return item else: matchObj=re.match(r'\d{4}/\d{2}/\d{2}\s\d+:\d+:\d+',item,flags=0 ) if matchObj!= None : item = time.strptime(item,'%Y/%m/%d %H:%M:%S') #print "returned time: %s " %item return item def ObjectGenerator(maxlinenum): filename='/home/thinkit/Documents/usr_info/USER.csv' attributes=[] linenum=1 a=UserInfo() file=open(filename) while linenum < maxlinenum: values=[] line=str.decode(file.readline(),'gb2312')#linecache.getline(filename, linenum,'gb2312') if line=='': print'reading fail! Please check filename!' break str_list=line.split(',') for item in str_list: item=item.strip() item=item.strip('\"') item=item.strip('\'') item=item.strip('+0*') item=catchTime(item) if linenum==1: attributes.append(item) else: values.append(item) if linenum==1: a.updateAttributes(attributes) else: a.updatePairs(values) yield a.attrilist #Change to ' a ' to use linenum = linenum +1 if __name__ == '__main__': for n in ObjectGenerator(10): print n # Visualizza il dizionario, controlla se è corretto
Sommario
Questo è tutto il contenuto dell'articolo, spero che possa essere di aiuto per la vostra apprendimento o lavoro. Se avete domande, potete lasciare un commento per discuterle, grazie per il supporto al tutorial urla.