>  기사  >  백엔드 개발  >  Python 클래스에서 동적으로 속성을 추가하고 객체를 생성합니다.

Python 클래스에서 동적으로 속성을 추가하고 객체를 생성합니다.

高洛峰
高洛峰원래의
2017-02-22 17:06:201026검색

본 글에서는 다음과 같은 측면을 통해 문제를 하나씩 해결해 나가겠습니다

1. 프로그램의 주요 기능

2. 구현 process

3. 클래스 정의

4. 생성기를 사용하여 각 개체를 동적으로 업데이트하고 개체를 반환합니다.

5. 스트립을 사용하여 불필요한 문자 제거

6. 일치하는 문자열 다시 일치

7. timestrptime을 사용하여 문자열을 추출하고 시간 개체로 변환

8. 전체 코드

프로그램의 주요 기능

이제 사용자 정보를 저장하는 표와 같은 문서가 있습니다. 첫 번째 줄은 속성이며, 각 속성은 두 번째 줄부터 시작하여 각 줄은 각 속성에 해당하는 값이며, 각 줄은 사용자를 나타냅니다. 이 문서를 읽고 한 줄에 하나의 사용자 개체를 출력하는 방법은 무엇입니까?
또한 4가지 작은 요구 사항이 있습니다.

각 문서가 매우 큽니다. 모든 행에서 생성된 너무 많은 개체가 목록에 저장되어 한 번에 반환되면 메모리가 무너집니다. 한 번에 하나의 라인 생성 객체만 프로그램에 저장할 수 있습니다.

쉼표로 구분된 각 문자열은 앞뒤에 큰따옴표(") 또는 작은따옴표(')가 올 수 있습니다. 예를 들어 "Zhang San"의 경우 따옴표를 제거해야 합니다. 숫자인 경우 이렇게 +000000001.24가 있을 수도 있습니다 예, 앞의 +와 0을 제거하고 1.24를 추출해야 합니다

문서에 시간이 있는데, 2013-10-29 형식일 수 있습니다. 이 양식과 같이 2013/10/29 2:23:56일 수 있으므로 이러한 문자열을 시간 유형으로 변환해야 합니다.

각각 다른 속성을 가진 문서가 많이 있습니다. 예를 들어 다음과 같습니다. 사용자 정보, 즉 통화 기록이므로 클래스의 세부 사항은 문서의 첫 번째 줄을 기반으로 어떤 속성을 동적으로 생성해야 하는지

구현 프로세스

1. 클래스 정의

속성은 동적으로 추가되므로 속성-값 쌍도 동적으로 추가됩니다. 🎜> 및 updateAttributes() 목록을 사용하여 속성을 저장합니다. updatePairs() 사전은 매핑을 저장합니다. attributes 앞의 밑줄은 개인 변수를 나타내며 그럴 수 없습니다. 인스턴스화할 때 attrilist만 필요합니다. >init()__attributes

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]
a=UserInfo()

2. object

생성기는 한 번만 초기화하면 자동으로 여러 번 실행되어 매번 결과를 반환할 수 있는 함수와 동일합니다. 🎜>를 사용하여 결과를 반환하고 생성기는 을 사용하여 매번 결과를 반환합니다. 모든 실행은
에서 반환되고 다음 실행은

이후에 시작됩니다. 생성기:

return 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;
yield<.>yield수열의 처음 6개 숫자를 계산합니다:

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

생성기를 사용하는 경우

로 변경하세요. OK 다음과 같이:

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

print yield 사용 방법:

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

보시다시피 생성기 fib 자체는 실행될 때마다 중단되고 다음 번부터 계속 실행됩니다.

의 코드 줄은

으로도 실행할 수 있습니다. 제 프로그램에서 생성기 부분 코드는 다음과 같습니다:

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
yieldgenerator.next()

그 중

클래스의 인스턴스화이므로 해당 문서는 gb2312로 인코딩되므로 위에서는 첫 번째 줄이 속성이므로 해당 속성을 저장하는 함수가 있다.

에 나열합니다. 즉,

뒤의 줄은 속성-값 쌍을 사전으로 읽어서 저장합니다.

의 사전은

a=UserInfo()3. Strip을 사용하여 불필요한 문자 UserInfoUserInfoupdateAttributes();p.s.python

를 제거합니다. 위 코드에서

을 사용하면 str 앞뒤의 문자를 제거할 수 있음을 알 수 있습니다. . 은 위와 같이 기호 또는 정규식일 수 있습니다.

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的个数可以任意多,也可以没有

str.strip(somechar)somecharsomechar4.re.match 일치 문자열

함수 구문:

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

함수 매개변수 설명:

매개변수 설명

pattern 정규식 일치


string 일치시킬 문자열입니다.

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中文网!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.