2011-09-13 30 views
4

在我的应用程序中,我生成了许多值(三列,类型为int,str和datetime,请参见下面的示例),并将这些值存储在平面文件中逗号分隔的字符串。此外,我存储一个包含值的类型的文件(见下文)。现在,如何使用这些信息将我的值从平面文件转换为Python中正确的数据类型?是可能的还是我需要做一些其他的东西?使用类型()信息来将值存储为字符串

数据文件:

#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是三个包含文件中值的字符串。 (请注意,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) 

然后你可以使用它像..:

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

不幸的是,日期时间,虽然这并不工作,因为它不能只需通过其字符串表示初始化即可

+1

虽然这**确实**正确地回答了这个问题,这是一个非常糟糕的方法。它有许多限制。例如,它仅限于默认的单参数转换。例如,更改日期时间格式会导致使用可以应用于输入的格式字符串创建闭包。这很快就会变成相当复杂的代码,这样即使有更简单的选择,getattr()和cls()也可以被强制使用。 –

+1

“type”不应​​该被称为 – dugres

+0

顺便说一下,指定从类型(a)获得'int'而不是(假设a是一个int类型的变量)可能会很有用, (一个名字__。但是,对于类型如,它将返回'float64'而不是'numpy.float64'。因此,根据情况,你也可以使用str(type(anObject))。split(“'”)[1]。 –

1

遵循以下步骤:

  1. 逐行读取文件中的行,每行执行以下步骤
  2. 拆分使用split(),作为分隔符。
  3. 将列表的第一个元素(来自第2步)作为int进行投射。将第二个元素保留为字符串。解析第三个值(e.g. using slices)并使相同的对象成为datetime
+0

嗨,阅读,分裂等完成。我试图实现一个泛型类型转换,使用类型文件中的信息。一般来说,我不知道列的类型是什么,这是类型文件在运行时必须告诉我的! – aweis

+0

Ohk!然后你只需要解析类型文件并将其存储在某个数据结构中,以便获得文件的结构。之后,您可以根据需要解析数据文件(但我认为您需要为'datetime'类型做些事情)。另外,泛型类型转换意味着内置类型还是任何用户定义类型?如果用户定义的类型也需要支持,那么编程就会非常糟糕。 :) – c0da

+0

是的,我已经这样做了,但最大的问题仍然是,我如何获得datetime.datetime对象从我的字符串'2011-09-13 15:00:00'在运行时(这些类型也可以是小数,浮点数等)我不能只使用简单的字符串匹配例如:tmp_type =='float':return float(val) – aweis

1

我不得不面对类似的情况在最近的一个项目中,必须转换很多领域。我使用了元组列表,其中元组的一个元素是要使用的转换函数。有时候是intfloat;有时候是简单的lambda;有时它是其他地方定义的函数的名称。

+0

请参阅OP的评论给你的答案。 OP已经完成了拆分并需要转换数据。我的回答说明对于简单的事情,你可以使用'int'等。对于'datetime'这样复杂的东西,你需要一个函数。使用这样的字段列表可让您以结构化的方式执行此操作。 –

+0

好吧,重新阅读它,它似乎确定... :)对不起,以前的倒票... – c0da

+0

我有我的想法转换功能,但我想有一个更通用的方法。我正在考虑一种'序列化'的方法,如果它可能在Python中! – aweis

0

而不是有一个单独的“类型”的文件,把你的元组列表(id, value, date)和只是pickle它。

或者您必须解决将字符串到类型转换器存储为文本(在您的“类型”文件中)的问题,这可能是一个有趣的问题,但如果您只是试图完成任务,与picklecPickle

0

首先,您不能编写一个神奇地处理任何事情的“通用”或“智能”转换。其次,试图在代码之外的任何其他任何事情中总结一个字符串到数据的转换似乎永远不会奏效。因此,不要编写名称转换的字符串,只需编写转换即可。

最后,试图用特定于领域的语言编写配置文件是愚蠢的。只需编写Python代码。这并不比试图解析某个配置文件复杂得多。

是可能的还是我需要做一些其他的东西?

不要浪费时间去尝试创建一个不仅仅是Python的“类型文件”。它没有帮助。将转换写为Python函数更简单。您可以将该功能导入为您的“类型文件”。

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

所以从我听到的是,没有'智能'的方式根据Python提供的类型信息将字符串值转换为特定类型。我需要创建一个转换功能我的自我?请注意,我的数据文件是自动生成的,在很多情况下,我不知道运行前的列数或数据类型! – aweis

+0

@aweis:“没有'聪明'的方式将字符串值转换为特定类型”? Python代码是将字符串转换为特定类型的* smart *方式。有太多的变化和选择以及可能的变化,您必须每次写**显式转换代码。没有真正的选择。 Python代码就是你如何写出“聪明”的东西。每种新的文件格式都可能意味着新的转换。有人必须编写“类型文件”。不管你认为你的代码如何“聪明”。 –

1

您的类型文件可以更简单:

id=int 
value=str 
date=datetime.datetime 

然后在你的主程序可以

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中,并且知道每个列与哪种类型相关联,那么当您读取excel文件时,xlrd会为您提供类型。当然,如果数据以csv的形式提供给你,那么有人需要进入excel文件并手动更改列类型。

不知道这会让你一路走到你想去的地方,但它可能有帮助

相关问题