English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Este artigo abordará um a um os seguintes aspectos para resolver
1Principais funcionalidades do programa
2Processo de implementação
3Definição da classe
4Uso de gerações `generator` para atualizar dinamicamente cada objeto e retornar o objeto
5Uso da função `strip` para remover caracteres desnecessários
6Uso de `rematch` para coincidir strings
7Utilize a função `timestrptime` para converter uma string em um objeto de tempo
8,código completo
Função principal do programa
Atualmente, há um documento semelhante a uma tabela para armazenar informações de usuários: a primeira linha é o atributo, e os atributos são separados por vírgula (,). A partir da segunda linha, cada linha é o valor correspondente a cada atributo, e cada linha representa um usuário. Como implementar a leitura desse documento, para que cada linha gere um objeto de usuário?
Além disso, há4pequenos requisitos:
Cada string separada por vírgula, que pode ter aspas duplas (+000000001.24Neste formato, é necessário remover o+E 0 são removidos, extraídos1.24
Os documentos contêm data, que pode ser2013-10-29Também pode ser2013/10/29 2:23:56 Neste formato, é necessário converter essa string em tipo de data
Existem muitos documentos desse tipo, e cada um tem atributos diferentes, por exemplo, este é a informação do usuário, e aquele é o registro de chamadas. Portanto, os atributos específicos da classe devem ser gerados dinamicamente com base no primeiro parágrafo do documento.
Processo de implementação
1.Definição da classe
Devido ao fato de que os atributos são adicionados dinamicamente, o atributo-Os valores também são adicionados dinamicamente. A classe deve conter os membros de função updateAttributes() e updatePairs(). Além disso, a lista attributes armazena os atributos e o dicionário attrilist armazena os mapeamentos. O função init() é o construtor. __attributes com sublinhado antes indica variável privada, que não pode ser chamada diretamente fora. Ao instanciar, é necessário apenas a=UserInfo(), sem quaisquer parâmetros.
class UserInfo(object): 'Classe para restaurar Informações do Usuário' def __init__ (self): self.attrilist={} self.__attributes=[] def atualizarAtributos(self,attributes): self.__attributes=attributes def atualizarPares(self,values): for i in range(len(values)): self.attrilist[self.__attributes[i]]=values[i]
2.Atualizar dinamicamente cada objeto e retornar o objeto usando gerador (generator)
Um gerador é uma função que precisa ser inicializada uma vez e pode ser executada várias vezes automaticamente, retornando um resultado a cada iteração. No entanto, a função retorna resultados usando return, enquanto o gerador retorna resultados usando yield. Cada execução ocorre no ponto de yield, e a próxima execução começa após o yield. Por exemplo, para implementar a sequência de Fibonacci, podemos usar uma função e um gerador:
def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a + b n = n + 1 return 'done'
Calculamos a sequência dos primeiros6Número de itens:
>>> fib(6) 1 1 2 3 5 8 'done'
Se usar um gerador, basta mudar print para yield. Veja a seguir:
def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1
Método de uso:
>>> f = fib(6) >>> f <generator object fib at 0x104feaaa0> >>> for i in f: ... print(i) ... 1 1 2 3 5 8 >>>
Podemos ver que o gerador fib em si é um objeto, sempre que o yield for executado, ele será interrompido e retornará um resultado, e a próxima vez que ele será continuado a partir da linha seguinte do yield. O gerador também pode ser executado com generator.next().
No meu código, a parte do gerador é como segue:
def GeradorDeObjeto(maxlinenum): filename='/casa/thinkit/Documentos/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 #mudar para 'a' para usar linenum = linenum +1
onde, a = UserInfo() é a instância da classe UserInfo. Porque o documento é gb2312Codificados, acima usou o método de decodificação correspondente. Devido à primeira linha ser um atributo, há uma função que armazena a lista de atributos no UserInfo, ou seja, updateAttributes(); as linhas subsequentes devem armazenar as-Valores para armazenar em um dicionário. p.s. o dicionário do python é equivalente a um mapeamento (map).
3.Usar strip para remover caracteres desnecessários
Do código acima, podemos ver que usar str.strip(somechar) é suficiente para remover os caracteres somechar antes e depois de str. somechar pode ser um símbolo ou uma expressão regular, como no exemplo acima:
item=item.strip()#Remover todos os caracteres de escape ao redor da string, como\t,\netc item=item.strip('\"')#Remover os caracteres antes e depois item=item.strip('\'') item=item.strip('"+0*')#Remover os caracteres antes e depois+00...00,*Representa o número zero que pode ser arbitrário, ou pode não haver
4.re.match correspond a string
Sintaxe da função:
re.match(pattern, string, flags=0)
Descrição dos parâmetros da função:
Parâmetros Descrição
pattern Expressão regular a ser correspondida
string String a ser correspondida
flags Sinalizador, usado para controlar o modo de correspondência da expressão regular, como: se diferenciar maiúsculas e minúsculas, correspondência de múltiplas linhas, etc.
Se o match for bem-sucedido, o método re.match retorna um objeto de correspondência, caso contrário, retorna None.
>>> s='2015-09-18'
>>> matchObj=re.match(r'\d{4}-\d{2}-\d{2}', s, flags= 0)
>>> print matchObj
<_sre.SRE_Match object at 0x7f3525480f38>
1
2
3
4
5
5Usar time.strptime para transformar uma string em um objeto de tempo
No módulo time, time.strptime(str, format) pode transformar str de acordo com o formato format em um objeto de tempo, os formatos comuns no format são:
%y ano de dois dígitos (00-99)
%Y ano de quatro dígitos (000-9999)
%m mês (01-12)
%d dia do mês (0-31)
%H 24número do horário em 12 horas (0-23)
%I 12número do horário em 12 horas (01-12)
%M minutos (00=59)
%S segundos (00-59)
Além disso, é necessário usar o módulo re, com expressões regulares, para coincidir strings, verificando se é um formato de tempo geral, como AAAA/MM/DD H:M:S, AAAA-MM-DD etc
Neste código, a função apanharHora verifica se item é um objeto de tempo, se for, converte para objeto de tempo.
Código a seguir:
import time import re def apanharHora(item): # verificar se é hora matchObj=re.match(r'\d{4}-\d{2}-\d{2}',item, flags= 0) if matchObj!= None : item = time.strptime(item,'%Y-%m-%d') #print "tempo devolvido: %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 "tempo devolvido: %s " %item return item
Código completo:
import collections import time import re class UserInfo(object): 'Classe para restaurar Informações do Usuário' def __init__ (self): self.attrilist=collections.OrderedDict()# ordenado self.__attributes=[] def atualizarAtributos(self,attributes): self.__attributes=attributes def atualizarPares(self,values): for i in range(len(values)): self.attrilist[self.__attributes[i]]=values[i] def apanharHora(item): # verificar se é hora matchObj=re.match(r'\d{4}-\d{2}-\d{2}',item, flags= 0) if matchObj!= None : item = time.strptime(item,'%Y-%m-%d') #print "tempo devolvido: %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 "tempo devolvido: %s " %item return item def GeradorDeObjeto(maxlinenum): filename='/casa/thinkit/Documentos/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 #mudar para 'a' para usar linenum = linenum +1 if __name__ == '__main__': for n in ObjectGenerator(10) print(n) #Imprimir dicionário, ver se está correto
Resumo
Isso é tudo o que há neste artigo, espero que ajude na sua aprendizagem ou trabalho. Se tiver alguma dúvida, pode deixar um comentário para trocar. Obrigado pelo apoio ao Tutorial Grito!