English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Dynamische hinzufügen von Eigenschaften in Klassen und Generierung von Objekten in Python

Dieser Artikel wird aus mehreren Aspekten schrittweise gelöst

      1、Hauptfunktion des Programms

      2、Implementierungsprozess

      3、Klassendefinition

      4、Dynamische Aktualisierung jedes Objekts und Rückgabe des Objekts durch den Generator generator

      5、Verwendung von strip, um unnötige Zeichen zu entfernen

      6、rematch zum Matching von Zeichenfolgen

      7、Verwendung von time.strptime, um Zeichenfolgen in Zeitobjekte umzuwandeln

      8, vollständiger Code

Hauptfunktion des Programms

Es gibt jetzt ein Dokument wie ein Tabellenblatt, um Benutzerinformationen zu speichern: Die erste Zeile ist die Eigenschaft, die Eigenschaften werden durch Kommata (,) getrennt, ab der zweiten Zeile ist jede Eigenschaft die entsprechenden Werte, jede Zeile repräsentiert einen Benutzer. Wie kann dieses Dokument gelesen werden, um jede Zeile einen Benutzerobjekt auszugeben?
Außerdem gibt es4kleine Anforderungen:

Jeder Dokument ist groß, wenn alle Zeilen gleichzeitig in eine Liste gespeichert werden, die so viele Objekte generiert werden, könnte der Speicher ausbrechen. In der Programmierung kann nur ein Zeilenobjekt pro Mal gespeichert werden.

00000000+voranstellen1.24solche zu extrahieren+und 0 werden entfernt, um1.24

Das Dokument enthält Zeit, die Form könnte sein2013-10-29, könnte es auch sein2013/10/29 2:23:56 in dieser Form, um solche Strings in Zeitart zu konvertieren

Solche Dokumente gibt es viele, und die Eigenschaften sind unterschiedlich, zum Beispiel ist das dieser Benutzerinformationen, und das andere ist die Anrufliste. Daher müssen die spezifischen Eigenschaften der Klasse gemäß dem ersten Eintrag des Dokuments dynamisch generiert werden

Implementierungsprozess

1.Klassendefinition

Da die Eigenschaften dynamisch hinzugefügt werden, die Eigenschaft-Werte auch dynamisch hinzufügen, die Klasse muss die beiden Memberfunktionen updateAttributes () und updatePairs () enthalten, sowie die Liste attributes speichern Eigenschaften und das Wörterbuch attrilist speichern Mapping. Der init () -Funktion ist der Konstruktor. Unterstrich __attributes bedeutet private Variable, die nicht direkt außen aufgerufen werden kann. Bei der Instanziierung ist nur a = UserInfo () erforderlich, ohne zusätzliche Parameter.

class UserInfo(object):
 'Klasse zum Wiederherstellen von Benutzerinformationen'
 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.Mit einem Generator (generator) dynamisch die Eigenschaften jedes Objekts aktualisieren und das Objekt zurückgeben

Ein Generator ist eine Funktion, die nur einmal initialisiert werden muss und mehrmals automatisch ausgeführt werden kann, wobei jedes Mal ein Ergebnis zurückgegeben wird. Der Funktion wird jedoch das Ergebnis mit return zurückgegeben, während der Generator das Ergebnis mit yield zurückgibt. Jedes Mal wird am yield zurückgegeben, und das nächste Mal beginnt die Ausführung nach yield. Zum Beispiel implementieren wir die Fibonacci-Folge mit einer Funktion und einem Generator:

def fib(max):
 n, a, b = 0, 0, 1
 while n < max:
  print(b)
  a, b = b, a + b
  n = n + 1
 return 'done'

Wir berechnen die ersten6Anzahl:

>>> fib(6)
1
1
2
3
5
8
'done'

Wenn Sie einen Generator verwenden, ändern Sie einfach print in yield. Zum Beispiel:

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

Verwendungsmethode:

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

可以看到,生成器fib本身是个对象,每次执行到yield会中断返回一个结果,下次又继续从yield的下一行代码继续执行。生成器还可以用generator.next()执行。

在我的程序中,生成器部分代码如下:

def ObjectGenerator(maxlinenum):
 filename='/Zuhause/thinkit/Dokumente/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

其中,a=UserInfo()为类UserInfo的实例化.因为文档是gb2312编码的,上面使用了对应的解码方法。由于第一行是属性,有个函数将属性列表存入UserInfo中,即updateAttributes();后面的行则要将 属性-值 对读入一个字典中存储。p.s.python中的字典相当于映射(map).

3.使用strip 去除不必要的字符

从上面代码中,可以看到使用str.strip(somechar)即可去除str前后的somechar字符。somechar可以是符号,也可以是正则表达式,如上:

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

4.re.match匹配字符串

函数语法:

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

函数参数说明:

参数           描述

pattern       匹配的正则表达式

string         要匹配的字符串。

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

Wenn das Muster erfolgreich gematcht wird, gibt die Methode re.match ein Match-Objekt zurück,否则返回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

5Verwenden Sie time.strptime, um eine Zeichenkette in ein Zeitobjekt umzuwandeln

Im Modul time kann time.strptime(str, format) eine Zeichenkette str nach dem Format format in ein Zeitobjekt umwandeln. Die gebräuchlichen Formate in format sind:

     %y Zweistelliges Jahr (00-99)

     %Y Vierstelliges Jahr (000-9999)

     %m Monat (01-12)

     %d Tag im Monat (0-31)

     %H 24Std. (0-23)

     %I 12Std. (01-12)

     %M Minuten (00=59)

     %S Sekunden (00-59)

Darüber hinaus muss das Modul re verwendet werden, um mit regulären Ausdrücken die Zeichenkette zu matchen und zu prüfen, ob sie im allgemeinen Zeitformat ist, wie YYYY/MM/DD H:M:S, YYYY-MM-DD et al.

In diesem Code ist die Funktion catchTime dafür verantwortlich, zu prüfen, ob item ein Zeitobjekt ist, und es in ein Zeitobjekt umzuwandeln, falls ja.

Der Code lautet wie folgt:

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 "zurückgegebene Zeit: %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 "zurückgegebene Zeit: %s " %item
  return item

Vollständiger Code:

import collections
import time
import re
class UserInfo(object):
 'Klasse zum Wiederherstellen von Benutzerinformationen'
 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 "zurückgegebene Zeit: %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 "zurückgegebene Zeit: %s " %item
  return item
def ObjectGenerator(maxlinenum):
 filename='/Zuhause/thinkit/Dokumente/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  # 输出字典,看是否正确

总结

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

Vielleicht gefällt dir