首頁  >  文章  >  後端開發  >  在python的類別中動態新增屬性與生成對象

在python的類別中動態新增屬性與生成對象

高洛峰
高洛峰原創
2017-02-22 17:06:201025瀏覽

本文將透過幾個面向來解決

      1、程式的主要功能

##      2、實現流程


      3.每個物件動態更新每個物件並回傳物件


      5、使用strip 移除不必要的字元


      6、rematch符合字串


      7、使用timestrptime提取字串轉換為時間物件


##  完整程式碼


程式的主要功能

#現在有個儲存使用者資訊的像表格一樣的文件:第一行是屬性,各個屬性以逗號(,)分隔,從第二行開始每行是各個屬性對應的值,每行代表一個使用者。如何實現讀入這個文檔,每行輸出一個使用者物件呢? 另外還有4個小要求:每個文件都很大,如果一次把所有行產生的那麼多物件存成列表返回,記憶體會崩潰。程式中每次只能存一個行所產生的物件。

用逗號隔開的每個字串,前後可能有雙引號(”)或單引號('),例如”張三“,要把引號去掉;如果是數字,有+000000001.24這樣的,要把前面的+和0都去掉,提取出1.24

文檔中有時間,形式​​可能是2013-10-29,也可能是2013/10/29 2:23:56 這樣的形式,要把這樣的字串轉成時間類型

這樣的文檔有好多個,每個的屬性都不一樣,例如這個是用戶的信息,那個是通話紀錄。屬性有哪些要根據文件的第一行動態產生

實作過程

1.類別的定義

#由於屬性是動態新增的,屬性-值對也是動態新增的,類別中要包含updateAttributes()
updatePairs()

兩個成員函數即可,此外用列表

attributes儲存屬性,字典attrilist儲存映射。前有底線表示私有變量,不能在外面直接呼叫。 ##2.用生成器(generator)動態更新每個物件並傳回物件產生器相當於一個只需要初始化一次,就可自動執行多次的函數,每次迴圈回傳一個結果。 ##yield返回,下次運行從yield之後開始。

我們計算數列的前6個數:

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]
如果用生成器的話,只要把print
改成

yield

就可以了。 ##可以看到,生成器fib本身就是個對象,每次執行到yield會中斷回傳一個結果,下次又繼續從yield的下一行程式碼繼續執行。器也可以用generator.next()執行。 在我的程式中,生成器部分程式碼如下:

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;

其中,

a=UserInfo()

為類別

UserInfo

的實例化.因為文件是gb2312編碼的,上面使用了對應的解碼方法。由於第一行是屬性,所以有函數將屬性清單存入

UserInfo

中,即updateAttributes();後面的行則要將屬性-值對讀入一個字典中儲存。 p.s.python中的字典相當於映射(map).

3.使用strip 移除不必要的字元

從上面程式碼中,可以看到使用

str.strip(somechar)

即可移除str前後的

somechar字元。 somechar可以是符號,也可以是正規表示式,如上:

#

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

4.re.match符合字串

函數語法:<pre class="brush:py;">def fib(max): n, a, b = 0, 0, 1 while n &lt; max: yield b a, b = b, a + b n = n + 1</pre>函數參數說明:

參數           說明#pattern       符合的正規表示式

string        string     <p>flags          标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。</p> <p>若匹配成功re.match方法返回一个匹配的对象,否则返回None。`</p> <p>>>> s='2015-09-18'<br>>>> matchObj=re.match(r'\d{4}-\d{2}-\d{2}',s, flags= 0)<br>>>> print matchObj<br>d3b49718cc712c0f68eee5f116f281b9<br>1<br>2<br>3<br>4<br>5<br></p> <p><span style="color: #ff0000"><strong>5.使用time.strptime提取字符串转化为时间对象</strong></span><br></p> <p>在<code>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):
 &#39;Class to restore UserInformation&#39;
 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&#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


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__ == &#39;__main__&#39;:
 for n in ObjectGenerator(10):
  print n  #输出字典,看是否正确

总结

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

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


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn