为什么在连接矩阵时会出现类型错误?

时间:2017-11-29 09:25:48

标签: python matrix eval

所以我正在使用这个代码,它应该从文本文件中返回两个矩阵的组合版本(没有导入任何类型的模块)。

def concatenate(filename): 
    with open(filename, 'r') as myfile:
        data=myfile.read().split()
        a=data[0].split()
        b=data[1].split()
    a=eval(a[0])
    b=eval(b[0])
    row_a=len(a)
    row_b=len(b)
    col_a=len(a[0])
    col_b=len(b[0])
    if row_a==row_b:
        concatenated=[a+b for a,b in zip(*eval(open(filename)))]        
        return concatenated
    if col_a==col_b:
        concatenated=[a+b for a, b in zip(*eval(open(filename)))]
        return concatenated
    else:
        print ("Error")

文本文件可能包含以下内容:

[[1,2],[3,4]] [[5,6,7],[8,9,10]]

输出:

[[1,2,5,6,7],[3,4,8,9,10]]

我继续得到这种类型错误:TypeError:eval()arg 1必须是字符串,字节或代码对象

我该如何解决这个问题?感谢。

2 个答案:

答案 0 :(得分:1)

  

我继续得到这种类型错误:TypeError:eval()arg 1必须是字符串,字节或代码对象

确实记录了这一点。

  

我该如何解决这个问题?

非常简单:不要将 render() { const dictionary = [ { value: 'grapefruit', label: 'Grapefruit' }, { value: 'lime', label: 'Lime' }, { value: 'coconut', label: 'Coconut' }, { value: 'mango', label: 'Mango' } ]; const options = []; dictionary.forEach(entry => options.push( <option value="grapefruit">{entry.label}</option> )); return ( <label> <select className="widefat" value={this.state.value} name={this.props.name} onChange={this.handleChange}> {options} </select> </label> ); } 对象传递给期望字符串,字节或代码对象的函数。

但实际上真正的解决方案是:完全使用file - 这是一个巨大的安全漏洞。至少使用eval()

ast.literal_eval()

此外,您无需重新打开文件(并忘记关闭它),您已经获得了>>> ast.literal_eval("[[1,2],[3,4]]") [[1, 2], [3, 4]] >>> ast.literal_eval("[[5,6,7],[8,9,10]]") [[5, 6, 7], [8, 9, 10]]

中的内容

答案 1 :(得分:0)

以下是使用ast.literal_eval()执行此操作的方法,这比在任意文件输入上运行危险eval更安全:

from ast import literal_eval

def concatenate(filename): 
    with open(filename, 'r') as myfile:
        data = myfile.read().split()
        result = literal_eval(data[0])
        b = literal_eval(data[1])
        if len(result) != len(b):
            print('Matrices of unequal length')
            return None    # or raise an exception

        for i, l in enumerate(result):
            l.extend(b[i])
        return result

对于您的数据:

>>> concatenate('data')
[[1, 2, 5, 6, 7], [3, 4, 8, 9, 10]]