3

大きなファイルを操作するPythonコードがいくつかあります。それらのいくつかでは、私は列間で操作を実行したり、それらの内容を選択したりします。入力ファイルはさまざまな構造を持つことができるため、この操作c3 + c5 -1または(c3<4) & (c5>4)(または組み合わせ)のような構文のコマンドラインを介して操作が提供されます。入力ファイルの4番目の列c4として解釈されます。

私のファイルは次のようになります('input_file.txt'):

21.3   4321.34   34.12   4   343.3  2  324
34.34  67.56     764.45  2   54.768 6  45265
986.96 87.98     234.09  1   54.456 3  5262
[...]

列4と列5を合計し、1
を減算するとします。

import re
import numpy as np

operation = "c3 + c5 -1"  #in reality given from command line
pattern = re.compile(r"c(\d+?)") # compile the regex that matches the column number
# get the actual expression to evaluate
to_evaluate = pattern.sub("ifile[:,\\1]", operation) 
#to_evaluate is: "ifile[:,3] + ifile[:,5] -1"

ifile = np.loadtxt('input_file.txt')
result = eval(to_evaluate)  #evaluate the operation required
print(result)
# do the rest

出力

[5、7、3、...]

私はこの実装を思いついたのは:

  1. ファイルの読み取り方法を変更したい場合(現時点ではまたはを使用することを決定できます)、または操作を追加したい場合は、書き込みと変更が簡単numpyですpandas
  2. 私にできることについて多くの自由を与えてくれます。c3 + c5 -1私は、(c3<4) & (c5>4)または(c2+c4)>0同じように扱うことができます。
  3. 私はすべてのコードで同じ署名を持っています:間違いを犯す可能性が低いです

これは安全ではない可能性があり(今のところ私がこれらのコードの唯一のユーザーですが)、対応するコードよりも遅くなる可能性があることを認識してevalいますが、これ以上の方法は考えられませんでした。

そのような操作を実装するためのより良い/より安全な方法を知っている人はいますか?

追加の編集:重要な場合は、Python2.7を実行しています

4

1 に答える 1

2

より安全な評価を行うことができます

def safe_eval(eval_str, variable_dict = None):
    '''welll... mostly safe:
        http://lybniz2.sourceforge.net/safeeval.html
    '''
    if variable_dict == None:
        variable_dict = {}
    return eval(eval_str, {"__builtins__" : None}, variable_dict)

Pythonをよく知っている人から完全に安全になることは決してありませんが(例についてはhttp://nedbatchelder.com/blog/201206/eval_really_is_dangerous.htmlを参照してください)

あなたのアプリケーションは私を混乱させているので、私があなたをどれだけ助けることができるかわかりません!


これがあなたがしていることを解決するのに役立つかどうかはわかりませんが、あなたができることの1つは、モジュール内のすべての関数を辞書にコンパイルすることです。

したがって、次のような方法で、使用する関数をコンパイルできます。

module_dict = {}
for n in dir(module):
 module_dict[n] = eval('module.'+n)

(この機能はPython 3の標準であると思います。つまり、すべてのモジュールモジュール辞書にアクセスできます。)これにより、すべての関数呼び出しが辞書形式になり、呼び出しが高速化されます。また、評価の安全性の問題も解決します。

'+'や'='などの操作を使用しようとしている場合は、オブジェクトから関数呼び出しを取得できます。追加してオブジェクトします。eq。これらの呼び出しを文字列構文に格納できます。

それが役立つかどうかはわかりません。

于 2013-03-15T17:12:26.463 に答える