English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
L'article traitera de la résolution de plusieurs aspects les uns après les autres
1、Fonctionnalités principales du programme
2、Processus d'implémentation
3、Définition de la classe
4、Mettre à jour dynamiquement chaque objet à l'aide d'un générateur et renvoyer l'objet
5、Utiliser `strip` pour supprimer les caractères inutiles
6、Recherche régulière pour correspondre à une chaîne
7、Utiliser `timestrptime` pour convertir une chaîne en objet de temps
8、完整代码
程序的主要功能
现在有个存储用户信息的像表格一样的文档:第一行是属性,各个属性用逗号(,)分隔,从第二行开始每行是各个属性对应的值,每行代表一个用户。如何实现读入这个文档,每行输出一个用户对象呢?
另外还有4个小要求:
每个文档都很大,如果一次性把所有行生成的那么多对象存成列表返回,内存会崩溃。程序中每次只能存一个行生成的对象。
用逗号隔开的每个字符串,前后可能有双引号(”)或者单引号('),例如”张三“,要把引号去掉;如果是数字,有+000000001.24这样的,要把前面的+和0都去掉,提取出1.24
文档中有时间,形式可能是2013-10-29,也可能是2013/10/29 2:23:56 这样的形式,要把这样的字符串转成时间类型
这样的文档有好多个,每个的属性都不一样,例如这个是用户的信息,那个是通话纪录。所以类中的具体属性有哪些要根据文档的第一行动态生成
实现过程
1.类的定义
由于属性是动态添加的,属性-值 对也是动态添加的,类中要含有updateAttributes()和updatePairs()两个成员函数即可,此外用列表attributes存储属性,词典attrilist存储映射。其中init()函数为构造函数。 __attributes前有下划线表示私有变量,不能在外面直接调用。实例化时只需a=UserInfo()即可,无需任何参数。
class UserInfo(object): 'Classe pour restaurer les informations utilisateur' 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.用生成器(generator)动态更新每个对象并返回对象
生成器相当于一个只需要初始化一次,就可自动运行多次的函数,每次循环返回一个结果。不过函数用return 返回结果,而生成器用yield 返回结果。每次运行都在yield返回,下一次运行从yield之后开始。例如,我们实现斐波拉契数列,分别用函数和生成器实现:
def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a + b n = n + 1 return 'done'
我们计算数列的前6个数:
>>> fib(6) 1 1 2 3 5 8 'done'
如果用生成器的话,只要把 print 改成 yield 就可以了。如下:
def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1
使用方法:
>>> f = fib(6) >>> f <generator object fib at 0x104feaaa0> >>> for i in f: ... print(i) ... 1 1 2 3 5 8 >>>
On peut voir que le générateur fib est un objet, chaque fois qu'il atteint yield, il se brise et retourne un résultat, puis il continue à exécuter à partir de la ligne de code après yield. Le générateur peut également être exécuté par generator.next().
Dans ma partie de code du générateur, voici :
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 #changer à ' a ' pour utiliser linenum = linenum +1
où, a=UserInfo() est l'instanciation de la classe UserInfo. Parce que le document est gb2312编码的, ci-dessus, a utilisé la méthode de décodage correspondante. En raison de la première ligne étant une propriété, il y a une fonction qui stocke la liste des attributs dans UserInfo, c'est-à-dire updateAttributes(); Les lignes suivantes doivent stocker les attributs-Les valeurs sont lues dans un dictionnaire et stockées. p.s. le dictionnaire en python est équivalent à une carte (map).
3.Utilisation de strip pour supprimer les caractères inutiles
À partir du code ci-dessus, on peut voir que l'utilisation de str.strip(somechar) permet de supprimer les caractères somechar avant et après str. somechar peut être un symbole, ou une expression régulière, comme ci-dessus :
item=item.strip()#Supprimer tous les caractères d'échappement avant et après la chaîne item=item.strip('\"')#Supprimer les guillemets avant et après item=item.strip(''') item=item.strip('+0*')#Supprimer les guillemets avant et après+00...00,*représente le nombre de 0 qui peut être arbitraire, ou il peut y en avoir aucun
4.re.match correspond à la chaîne
Syntaxe de la fonction :
re.match(pattern, string, flags=0)
Description des paramètres de la fonction :
paramètres Description
pattern Expression régulière à correspondre
string Chaîne à correspondre
flags Indicateur, utilisé pour contrôler le mode de correspondance de l'expression régulière, comme : distinction des majuscules et minuscules, correspondance en plusieurs lignes, etc.
Si le match est réussi, la méthode re.match retourne un objet de correspondance, sinon elle retourne 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
5Utilisation de time.strptime pour convertir une chaîne en objet de temps
Dans le module time, time.strptime(str, format) peut convertir str en objet de temps suivant le format, les formats courants dans format sont :
%y Année à deux chiffres (00-99)
%Y Année à quatre chiffres (000-9999)
%m Mois (01-12)
%d Jour du mois (0-31)
%H 24Heures en mode 12 (0-23)
%I 12Heures en mode 12 (01-12)
%M minutes (00=59)
%S secondes (00-59)
De plus, il est nécessaire d'utiliser le module re, avec des expressions régulières, pour correspondre aux chaînes de caractères, pour voir s'il s'agit d'un format de temps habituel, comme AAAA/MM/DD H:M:S, AAAA-MM-DD
Dans le code ci-dessus, la fonction catchTime juge si item est un objet de temps, s'il l'est, il le convertit en objet de temps.
Code suivant :
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
Code complet :
import collections import time import re class UserInfo(object): 'Classe pour restaurer les informations utilisateur' 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 #changer à ' a ' pour utiliser linenum = linenum +1 if __name__ == '__main__': for n in ObjectGenerator(10) : print n # Afficher le dictionnaire, vérifier s'il est correct
Résumé
Ceci est le contenu intégral de cet article, j'espère qu'il apportera un certain avantage à votre apprentissage ou à votre travail. Si vous avez des questions, vous pouvez laisser des commentaires pour échanger. Merci de votre soutien à la tutelle d'alarme.