理解期间列表中的python类型

Pey*_*man 1 python types

我有一个SQL查询字符串,如下所示:

intro text,
id int,
description varchar(50)
Run Code Online (Sandbox Code Playgroud)

我正在尝试创建一个类型的字符串,目的是查找与sql架构中定义的类型不匹配的文本片段.我从sql文本中提取类型的方式如下:

types = [re.sub('[^a-zA-Z]','',x.split()[1]) for x in schema] 
types = [re.sub('varchar',types.StringType,x) for x in types]
types = [re.sub('text',types.StringType,x) for x in types]
types = [re.sub('bigint',types.IntType,x) for x in types]
types = [re.sub('decimal',types.IntType,x) for x in types]
Run Code Online (Sandbox Code Playgroud)

然而,翻译抱怨说

types = [re.sub('varchar',types.StringTypes,x) for x in types]
AttributeError: 'list' object has no attribute 'StringTypes'
Run Code Online (Sandbox Code Playgroud)

一个SSCCE

使用以下模式文件

intro text,
id int,
description varchar(50)
Run Code Online (Sandbox Code Playgroud)

和代码(注意,如下面的oscar建议的修复,但现在有其他错误)

import csv
import sys
import re
import types

sch = open(sys.argv[1], "rb")

#---------------------------------   
# read schema
#---------------------------------     
with sch as f:
    schema = f.read().splitlines()

#---------------------------------    
# extract schema types
#---------------------------------  

foundtypes = [re.sub('[^a-zA-Z]','',x.split()[1]) for x in schema] 
foundtypes = [re.sub('varchar',str,x) for x in foundtypes]
foundtypes = [re.sub('text',str,x) for x in foundtypes]
foundtypes = [re.sub('int',int,x) for x in foundtypes]
foundtypes = [re.sub('bigint',int,x) for x in foundtypes]
foundtypes = [re.sub('decimal',int,x) for x in foundtypes]

print foundtypes
Run Code Online (Sandbox Code Playgroud)

我使用的是Python 2.7.5

谢谢

Ósc*_*pez 5

您在该行中覆盖了对模块的绑定(请参阅:变量阴影):types

types = [re.sub('[^a-zA-Z]','',x.split()[1]) for x in schema]
Run Code Online (Sandbox Code Playgroud)

之后,types不再指向模块,而是指向列表.只需在所有作业中使用其他名称:

my_types = [re.sub('[^a-zA-Z]','',x.split()[1]) for x in schema] 
my_types = [re.sub('varchar',types.StringType,x) for x in my_types]
my_types = [re.sub('text',types.StringType,x) for x in my_types]
my_types = [re.sub('bigint',types.IntType,x) for x in my_types]
my_types = [re.sub('decimal',types.IntType,x) for x in my_types]
Run Code Online (Sandbox Code Playgroud)

UPDATE

我认为你过度设计了解决方案,除了第一行,这不适合使用正则表达式.一个简单的if-elif-else工作就好了:

def transform(typestr):
    if typestr in ('varchar', 'text'):
        return types.StringType
    elif typestr in ('int', 'bigint', 'decimal'):
        return types.IntType
    else:
        return None

my_types = [re.sub(r'[^a-zA-Z]', '', x.split()[1]) for x in schema] 
[transform(x) for x in my_types]
=> [<type 'str'>, <type 'int'>, <type 'str'>]
Run Code Online (Sandbox Code Playgroud)