본 글에서는 다음과 같은 측면을 통해 문제를 하나씩 해결해 나가겠습니다
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 'done'
yield
<. 🎜>yield
수열의 처음 6개 숫자를 계산합니다: >>> fib(6) 1 1 2 3 5 8 'done'
생성기를 사용하는 경우
를로 변경하세요. 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='/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 #change to ' a ' to use linenum = linenum +1
yield
generator.next()
그 중 은
클래스의 인스턴스화이므로 해당 문서는 gb2312로 인코딩되므로 위에서는 첫 번째 줄이 속성이므로 해당 속성을 저장하는 함수가 있다.에 나열합니다. 즉,
뒤의 줄은 속성-값 쌍을 사전으로 읽어서 저장합니다.의 사전은
a=UserInfo()
<과 같습니다. 🎜>3. Strip을 사용하여 불필요한 문자 UserInfo
UserInfo
updateAttributes();
p.s.python
을 사용하면 str 앞뒤의 문자를 제거할 수 있음을 알 수 있습니다. . 은 위와 같이 기호 또는 정규식일 수 있습니다.
item=item.strip()#除去字符串前后的所有转义字符,如\t,\n等 item=item.strip('\"')#除去前后的" item=item.strip('\'') item=item.strip('+0*')#除去前后的+00...00,*表示0的个数可以任意多,也可以没有
str.strip(somechar)
somechar
somechar
4.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
<_sre.SRE_Match object at 0x7f3525480f38>
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'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
完整代码:
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='/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 #change to ' a ' to use linenum = linenum +1 if __name__ == '__main__': for n in ObjectGenerator(10): print n #输出字典,看是否正确
总结
以上就是这篇文章的全部内容,希望能对大家的学习或者工作带来一定帮助,如果有疑问大家可以留言交流,谢谢大家对PHP中文网的支持。
更多在python的类中动态添加属性与生成对象相关文章请关注PHP中文网!