2011-09-13 3 views
4

제 응용 프로그램에서는 여러 값 (int 열, str 열 및 datetime 열 3 열)을 생성했으며 이러한 값은 다음과 같이 플랫 파일에 저장됩니다. 쉼표로 구분 된 문자열. 게다가, 나는 값의 유형을 담고있는 파일을 저장한다. (아래 참조). 이제이 정보를 사용하여 플랫 파일의 값을 파이썬의 올바른 데이터 유형으로 변환 할 수 있습니까? 가능합니까 아니면 다른 것들을 할 필요가 있습니까?문자열로 저장된 값을 캐스팅하는 데 type() 정보를 사용합니다.

데이터 파일 :

#id,value,date 
1,a,2011-09-13 15:00:00 
2,b,2011-09-13 15:10:00 
3,c,2011-09-13 15:20:00 
4,d,2011-09-13 15:30:00 

유형 파일 :

id,<type 'int'> 
value,<type 'str'> 
date,<type 'datetime.datetime'> 

답변

2

필자가 이미 파일을 구문 분석했다는 것을 알았으므로 이제는 올바른 형식 만 입력하면됩니다. 따라서 id_, type_value은 파일의 값을 포함하는 3 개의 문자열입니다. (type_ 예를 —에 대한 'int' —를 포함해야합니다, 참고하지 '<type 'int'>'

그런 다음
def convert(value, type_): 
    import importlib 
    try: 
     # Check if it's a builtin type 
     module = importlib.import_module('__builtin__') 
     cls = getattr(module, type_) 
    except AttributeError: 
     # if not, separate module and class 
     module, type_ = type_.rsplit(".", 1) 
     module = importlib.import_module(module) 
     cls = getattr(module, type_) 
    return cls(value) 

당신이 원하는 사용할 수 있습니다 .. :. 불행하게도,이 나던 작업하지만 DateTime의

value = convert("5", "int") 

로는 할 수 없습니다

+1

**이 ** ** 질문에 올바르게 대답하지만 실제로는 좋지 않습니다. 수많은 제한이 있습니다. 예를 들어 기본 단일 변수 전환으로 제한됩니다. 예를 들어 datetime 형식을 변경하면 입력에 적용 할 수있는 형식 문자열을 사용하여 클로저가 작성됩니다. 이것은 상당히 복잡한 코드로 빠르게 옮겨져보다 간단한 대안이있을 때에도'getattr()'과'cls()'가 강제로 작동 될 수 있습니다. –

+1

"type"을 호출해서는 안됩니다. – dugres

+0

그런데 유형 (a)에서 대신에 'int'를 얻도록 지정하는 것이 유용 할 수 있습니다 (a가 int 유형의 변수 인 경우). type (이름__. 그러나 와 같은 유형의 경우 'float64'가 반환되고 'numpy.float64'는 반환되지 않습니다. 따라서 상황에 따라 str (type (anObject)). split (" '"[1])을 사용할 수도 있습니다. –

1

다음 단계에 따라 각 행에 대해 다음 단계를 수행

  1. 라인하여 파일 라인을 읽기를
  2. split()과를 사용하여 줄을 나눕니다.을 분리기로 사용하십시오.
  3. 목록의 첫 번째 요소 (2 단계에서 가져옴)를 int로 캐스트합니다. 두 번째 요소는 문자열로 유지하십시오. 세 번째 값인 (e.g. using slices)을 구문 분석하고 datetime 개체를 동일하게 만듭니다.
+0

안녕하세요, 읽기, 나누기 등이 수행됩니다. 형식 파일의 정보를 사용하여 변환하는 제네릭 형식을 구현하려고합니다. 일반적으로 어떤 유형의 열이 있는지 전혀 모르겠다. 이것은 유형 파일이 런타임에 알려줘야하는 것입니다! – aweis

+0

오크! 그런 다음 형식 파일을 구문 분석하고 일부 데이터 구조에 저장하여 파일 구조를 가져와야합니다. 그 후에 필요에 따라 데이터 파일을 구문 분석 할 수 있습니다 (하지만'datetime' 유형에 대해 뭔가해야 할 필요가 있다고 생각합니다). 또한 일반 유형 변환은 기본 제공 유형 또는 사용자 정의 유형을 의미합니까?사용자 정의 유형도 지원되어야한다면 많은 양의 프로그래밍이 필요합니다. :) – c0da

+0

예, 저도 해 봤지만 큰 문제는 여전히 있습니다. datetime.datetime 객체 '내 문자열에서'2011-09-13 15:00:00 '런타임 (이러한 유형도 Decimal, 부동 등 수 있습니다.) 난 그냥 일치하는 간단한 문자열을 사용 예 : tmp_type =='플로트 ': 반환 float (val) – aweis

1

많은 분야를 변환해야했던 최근 프로그램에서 비슷한 상황을 처리해야했습니다. 나는 튜플 목록을 사용했다. 튜플의 한 요소는 사용할 변환 함수였다. 때로는 int 또는 float이었습니다. 때때로 그것은 단순한 lambda이었다; 때로는 다른 곳에서 정의 된 함수의 이름이었습니다.

+0

대답에 OP의 주석을 보라. OP는 분할을 완료했으며 데이터를 변환해야합니다. 내 대답은 그것을 해결합니다. 간단한 일을 위해서, 당신은'int' 등을 사용합니다. 'datetime'과 같은 복잡한 것들을 위해서, 당신은 함수를 원합니다. 이와 같이 필드 목록을 사용하면 구조화 된 방식으로이 작업을 수행 할 수 있습니다. –

+0

좋아요, 다시 읽으세요. 괜찮아 보이는군요. :) 이전 다운 표기에 ... 죄송합니다 ... – c0da

+0

저는 변환 기능에 대한 생각을 갖고 있지만보다 일반적인 접근 방식을 원합니다. 파이썬에서 가능하다면 접근 방식과 같은 '직렬화'를 생각하고 있습니다! – aweis

0

별도의 "유형"파일을 갖는 대신 (id, value, date)의 튜플 목록을 가져 와서 pickle 개만 가져옵니다.

또는 문자열 - 유형 변환기를 텍스트 ("유형"파일)에 저장하는 문제를 해결해야합니다. 문제는 해결할 재미가 있지만, 완료 무언가를 얻으십시오 pickle 또는 cPickle

0

첫째, 당신은 마법 같은 취급 아무것도 "보편적 인"또는 "스마트"전환을 작성할 수 없습니다.

둘째, 코드 이외의 다른 것으로 문자열 - 데이터 변환을 요약하려고 시도하면 결코 잘 해결되지 않는 것 같습니다. 따라서 변환의 이름을 지정하는 문자열을 작성하는 대신 변환을 작성하십시오.

마지막으로, 도메인 특정 언어로 구성 파일을 쓰려고하면 어리석은 일입니다. 그냥 파이썬 코드를 작성하십시오. 구성 파일을 구문 분석하는 것보다 훨씬 복잡합니다.

다른 것들을 할 필요가 있습니까?

파이썬이 아닌 "유형 파일"을 만들려고 시간을 낭비하지 마십시오. 도움이되지 않습니다. 변환을 파이썬 함수로 작성하는 것이 더 간단합니다. 해당 함수를 "유형 파일"처럼 가져올 수 있습니다. 당신이 당신의 "형식 파일"

이제

당신이 읽을 수 (및 프로세스)이 같은 귀하의 의견에 모두의

import datetime 

def convert(row): 
    return dict(
     id= int(row['id']), 
     value= str(row['value']), 
     date= datetime.datetime.strptime(row['date],"%Y-%m-%d %H:%M:%S"), 
    ) 

.많은 경우에

from type_file import convert 
import csv 

with open("date", "rb") as source: 
    rdr= csv.DictReader(source) 
    for row in rdr: 
     useful_row= convert(row) 

은 내가 열 수 또는 이것은 당신이 운명을 의미 런타임

전에 데이터 유형을 알 수 없습니다.

파일 내용이 실제 정의되어 있어야합니다. 그렇지 않으면 처리 할 수 ​​없습니다.

"id","value","other value" 
1,23507,3 
"23507"은 (일 또는 초) 정수, 문자열, 우편 번호, 또는 (기간을 생략) 부동 소수점, 기간해야하는 경우가 모르는

또는 일부 다른 복잡한 일. 희망을 가질 수없고 추측 할 수 없습니다.

정의를 얻은 후에는 실제 정의에 따라 명시 적 변환 함수를 작성해야합니다.

변환을 작성한 후에는 (a) 간단한 단위 테스트로 변환을 테스트하고 (b) 데이터가 실제로 변환되는지 테스트해야합니다.

그런 다음 파일을 처리 할 수 ​​있습니다.

+0

그래서 제가 듣기로는 파이썬에서 제공하는 유형 정보를 기반으로 특정 유형에 문자열 값을 캐스팅하는 '스마트 한'방법이 없다는 것입니다. 내 자신을 변환 기능을 만들어야합니까? 내 데이터 파일은 자동으로 생성되며 대부분의 경우 런타임 전에 데이터 유형이나 열 수를 알지 못합니다. – aweis

+0

@aweis : "문자열 값을 특정 유형으로 변환하는 '현명한'방법이 없습니다." 파이썬 코드는 문자열을 특정 형식으로 변환하는 * 스마트 한 방법입니다. 매번 명시 적 변환 코드를 작성해야하는 많은 변경 사항과 선택 사항 및 가능한 변경 사항이 있습니다. 진짜 선택의 여지가 없습니다. 파이썬 코드는 "똑똑한"것들을 작성하는 방법입니다. 각각의 새로운 파일 형식은 새로운 변환을 의미 할 수 있습니다. 누군가 "형식 파일"을 작성해야합니다. 아무리 똑똑해도 코드가 될 수 있다고 생각합니다. –

1

유형 파일은 더 간단 할 수 있습니다 :

그런 다음 메인 프로그램에서 당신은

import datetime 

def convert_datetime(text): 
    return datetime.datetime.strptime(text, "%Y-%m-%d %H:%M:%S") 

data_types = {'int':int, 'str':str, 'datetime.datetime':convert_datetime} 
fields = {} 

for line in open('example_types.txt').readlines(): 
    key, val = line.strip().split('=') 
    fields[key] = val 

data_file = open('actual_data.txt') 
field_info = data_file.readline().strip('#\n ').split(',') 
values = [] #store it all here for now 

for line in data_file.readlines(): 
    row = [] 
    for i, element in enumerate(line.strip().split(',')): 
     element_type = fields[field_info[i]] # will get 'int', 'str', or 'datetime' 
     convert = data_types[element_type] 
     row.append(convert(element)) 
    values.append(row) 

# to show it working... 
for row in values: 
    print row 
0

당신은 xlrd 모듈에서 볼 수도 있습니다. 데이터를 Excel로로드 할 수 있고 각 열과 연결된 유형을 알고있는 경우 xlrd는 Excel 파일을 읽을 때 유형을 제공합니다. 물론 데이터가 CSV로 제공되면 다른 사람이 Excel 파일로 이동하여 직접 열 유형을 변경해야합니다.

잘 모르겠지만 도움이 될 수 있습니다.

관련 문제