Heim  >  Artikel  >  Backend-Entwicklung  >  Fügen Sie Attribute dynamisch hinzu und generieren Sie Objekte in Python-Klassen

Fügen Sie Attribute dynamisch hinzu und generieren Sie Objekte in Python-Klassen

高洛峰
高洛峰Original
2017-02-22 17:06:201066Durchsuche

Dieser Artikel wird das Problem einzeln anhand der folgenden Aspekte lösen

1. Hauptfunktionen des Programms

2. Implementierung Prozess

3. Klassendefinition

4. Verwenden Sie den Generatorgenerator, um jedes Objekt dynamisch zu aktualisieren und das Objekt zurückzugeben

5. Verwenden Sie Strip um unnötige Zeichen zu entfernen

6. Passende Zeichenfolge erneut abgleichen

7. Verwenden Sie timestrptime, um die Zeichenfolge zu extrahieren und in ein Zeitobjekt umzuwandeln

8. Vollständiger Code

Hauptfunktionen des Programms

Jetzt gibt es ein tabellenartiges Dokument, das Benutzerinformationen speichert: Die erste Zeile ist Attribute, jedes Attribut wird durch Kommas (,) getrennt. Ab der zweiten Zeile ist jede Zeile der Wert, der jedem Attribut entspricht, und jede Zeile repräsentiert einen Benutzer. Wie lese ich dieses Dokument und gebe ein Benutzerobjekt pro Zeile aus?
Es gibt außerdem 4 kleine Anforderungen:

Jedes Dokument ist sehr groß, wenn so viele von allen Zeilen generierte Objekte in einer Liste gespeichert und auf einmal zurückgegeben werden, bricht der Speicher zusammen. Es kann jeweils nur ein zeilengeneriertes Objekt im Programm gespeichert werden.

Jeder durch Kommas getrennte Zeichenfolge können doppelte Anführungszeichen (") oder einfache Anführungszeichen (') vorangestellt und gefolgt werden. Beispielsweise müssen für „Zhang San“ die Anführungszeichen entfernt werden. Wenn es sich um eine Zahl handelt, Es kann +000000001,24 wie folgt geben. Ja, Sie müssen das + und die 0 vorn entfernen und 1,24 extrahieren.

Das Dokument enthält eine Zeitangabe, die möglicherweise die Form 29.10.2013 oder hat Es kann wie folgt aussehen: 29.10.2013 2:23:56 Sie müssen eine solche Zeichenfolge in einen Zeittyp konvertieren

Es gibt viele solcher Dokumente, jedes mit unterschiedlichen Attributen. Dies ist beispielsweise Benutzerinformationen, also Anrufdatensätze, also die Einzelheiten in der Klasse, die basierend auf der ersten Zeile des Dokuments dynamisch generiert werden sollen

Implementierungsprozess

1. Klassendefinition

Da Attribute dynamisch hinzugefügt werden, müssen Attribut-Wert-Paare auch dynamisch hinzugefügt werden, updateAttributes() und updatePairs(), und verwenden Sie eine Liste attributes, um Attribute zu speichern. Die Funktion attrilist ist ein Konstruktor, der angibt, dass sie nicht direkt aufgerufen werden kann von außen. Es braucht nur init() beim Instanziieren, ohne Parameter >__attributesa=UserInfo()

class UserInfo(object):
 'Class to restore UserInformation'
 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 und geben Sie das Objekt zurück

Der -Generator entspricht einer Funktion, die nur einmal initialisiert werden muss und automatisch mehrmals ausgeführt werden kann. Allerdings gibt jede Schleife ein Ergebnis zurück. Die Funktion verwendet , um das Ergebnis zurückzugeben, während der Generator verwendet, um das Ergebnis zurückzugeben. Jeder Lauf kehrt bei
zurück und der nächste Lauf beginnt nach

. Beispielsweise implementieren wir die Fibonacci-Folge mit Funktionen und Generatoren:

return yield yieldWir berechnen die ersten 6 Zahlen der Folge: yield

def fib(max):
 n, a, b = 0, 0, 1
 while n < max:
  print(b)
  a, b = b, a + b
  n = n + 1
 return &#39;done&#39;

Wenn Sie einen Generator verwenden, geben Sie einfach

ein. Ändern Sie es einfach wie folgt in

:

>>> fib(6)
1
1
2
3
5
8
&#39;done&#39;

print Nutzung : yield

def fib(max):
 n, a, b = 0, 0, 1
 while n < max:
  yield b
  a, b = b, a + b
  n = n + 1

Sie können sehen, dass die Generator-Fib selbst ein Objekt ist. Jedes Mal, wenn sie zum Nachgeben ausgeführt wird, wird sie unterbrochen und ein Ergebnis zurückgegeben. Beim nächsten Mal wird die Ausführung ab der nächsten Codezeile in

fortgesetzt. Der Generator-Teilcode lautet in meinem Programm auch wie folgt:

>>> f = fib(6)
>>> f
<generator object fib at 0x104feaaa0>
>>> for i in f:
...  print(i)
... 
1
1
2
3
5
8
>>>

wobei yield die Klasse ist. Da das Dokument gb2312-codiert ist, wird oben die entsprechende Dekodierungsmethode verwendet. Da die erste Zeile das Attribut ist, gibt es eine Funktion zum Speichern der Attributliste in generator.next(), d. h. die Zeilen nach

werden die Attribut-Wert-Paare in ein Wörterbuch einlesen und im Wörterbuch in entspricht einer Karte

3. Verwenden Sie den Streifen, um unnötige Zeichen zu entfernen
def ObjectGenerator(maxlinenum):
 filename=&#39;/home/thinkit/Documents/usr_info/USER.csv&#39;
 attributes=[]
 linenum=1
 a=UserInfo()
 file=open(filename)
 while linenum < maxlinenum:
  values=[]
  line=str.decode(file.readline(),&#39;gb2312&#39;)#linecache.getline(filename, linenum,&#39;gb2312&#39;)
  if line==&#39;&#39;:
   print&#39;reading fail! Please check filename!&#39;
   break
  str_list=line.split(&#39;,&#39;)
  for item in str_list:
   item=item.strip()
   item=item.strip(&#39;\"&#39;)
   item=item.strip(&#39;\&#39;&#39;)
   item=item.strip(&#39;+0*&#39;)
   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 &#39; a &#39; to use
  linenum = linenum +1

Mit dem obigen Code können Sie Beachten Sie, dass mit a=UserInfo() die UserInfo-Zeichen vor und nach str entfernt werden können. UserInfo kann ein Symbol oder ein regulärer Ausdruck sein, wie oben: updateAttributes();p.s.python


4.re.match passende Zeichen Zeichenfolge

str.strip(somechar)somecharsomecharFunktionssyntax:

item=item.strip()#除去字符串前后的所有转义字符,如\t,\n等
item=item.strip(&#39;\"&#39;)#除去前后的"
item=item.strip(&#39;\&#39;&#39;)
item=item.strip(&#39;+0*&#39;)#除去前后的+00...00,*表示0的个数可以任意多,也可以没有

Funktionsparameterbeschreibung: Parameter Beschreibung

Muster Passender regulärer Ausdruck

Zeichenfolge Die Zeichenfolge, die abgeglichen werden soll.

re.match(pattern, string, flags=0)

flags          标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

若匹配成功re.match方法返回一个匹配的对象,否则返回None。`

>>> s='2015-09-18'
>>> matchObj=re.match(r'\d{4}-\d{2}-\d{2}',s, flags= 0)
>>> print matchObj
d3b49718cc712c0f68eee5f116f281b9
1
2
3
4
5

5.使用time.strptime提取字符串转化为时间对象

time模块中,time.strptime(str,format)可以把str按照format格式转化为时间对象,format中的常用格式有:

     %y 两位数的年份表示(00-99)

     %Y 四位数的年份表示(000-9999)

     %m 月份(01-12)

     %d 月内中的一天(0-31)

     %H 24小时制小时数(0-23)

     %I 12小时制小时数(01-12)

     %M 分钟数(00=59)

     %S 秒(00-59)

此外,还需要使用re模块,用正则表达式,对字符串进行匹配,看是否是一般时间的格式,如YYYY/MM/DD H:M:S, YYYY-MM-DD

在上面的代码中,函数catchTime就是判断item是否为时间对象,是的话转化为时间对象。

代码如下:

import time
import re

def catchTime(item):
 # check if it&#39;s time
 matchObj=re.match(r&#39;\d{4}-\d{2}-\d{2}&#39;,item, flags= 0)
 if matchObj!= None :
  item =time.strptime(item,&#39;%Y-%m-%d&#39;)
  #print "returned time: %s " %item
  return item
 else:
  matchObj=re.match(r&#39;\d{4}/\d{2}/\d{2}\s\d+:\d+:\d+&#39;,item,flags=0 )
  if matchObj!= None :
   item =time.strptime(item,&#39;%Y/%m/%d %H:%M:%S&#39;)
   #print "returned time: %s " %item
  return item

完整代码:

import collections
import time
import re

class UserInfo(object):
 'Class to restore UserInformation'
 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=&#39;/home/thinkit/Documents/usr_info/USER.csv&#39;
 attributes=[]
 linenum=1
 a=UserInfo()
 file=open(filename)
 while linenum < maxlinenum:
  values=[]
  line=str.decode(file.readline(),&#39;gb2312&#39;)#linecache.getline(filename, linenum,&#39;gb2312&#39;)
  if line==&#39;&#39;:
   print&#39;reading fail! Please check filename!&#39;
   break
  str_list=line.split(&#39;,&#39;)
  for item in str_list:
   item=item.strip()
   item=item.strip(&#39;\"&#39;)
   item=item.strip(&#39;\&#39;&#39;)
   item=item.strip(&#39;+0*&#39;)
   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 &#39; a &#39; to use
  linenum = linenum +1

if __name__ == '__main__':
 for n in ObjectGenerator(10):
  print n  #输出字典,看是否正确

总结

以上就是这篇文章的全部内容,希望能对大家的学习或者工作带来一定帮助,如果有疑问大家可以留言交流,谢谢大家对PHP中文网的支持。

更多在python的类中动态添加属性与生成对象相关文章请关注PHP中文网!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn