Skip to main content
 首页 » 编程设计

理解期间列表中的python类型

2025年05月04日16Free-Thinker

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

intro text, 
id int, 
description varchar(50) 

我正在尝试创建一个类型字符串,目的是找到与 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] 

然而口译员提示说

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

一个SSCCE

使用以下架构文件

intro text, 
id int, 
description varchar(50) 

和代码(注意,按照下面 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 

我正在使用 Python 2.7.5

谢谢

请您参考如下方法:

您将绑定(bind)(参见:variable shadowing)改写为 types module , 在这一行中:

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

之后,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] 

更新

我认为您过度设计了解决方案,除了第一行,这不适合使用正则表达式。一个简单的 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'>]