2009-07-17 15 views
1

私は、変数型、変数名、プロンプト、およびデフォルト値のリストを渡すことができるクラスを作成しました。このクラスはwxPythonパネルを作成します。これはフレームに表示され、計算ボタンを押して結果をプロットとして戻す前に入力値を設定できます。私は、exec文を使ってクラスにすべての変数を追加します。これにより、すべての変数が1つのクラスにまとめられ、名前で参照することができます。PythonでEvalを使用してクラス変数を作成

light = Variables(frame , [ ['f','wavelength','Wavelength (nm)',632.8] ,\ 
          ['f','n','Index of Refraction',1.0],]) 

私が作成したクラス内などでたstatmentsで変数を設定します。私は、変数を使用する必要があるとき、私は名前だけでそれらを参照することができ

for variable in self.variable_list: 
     var_type,var_text_ctrl,var_name = variable 
     if var_type == 'f' : 
      exec('self.' + var_name + ' = ' + var_text_ctrl.GetValue()) 

wl = light.wavelength 
n = light.n 

次に、私は、ほとんどの場合、Pythonでexecを使用する必要がないことを読んでいます。このアプローチに問題はありますか?一緒にグループ化し、編集できるようにする変数を保持するクラスを作成するより良い方法はありますか?また、コードを表示したり、編集したり(そしてすべての変数をファイルに保存するためのwxPythonコールがあります)またはそれらを再び読んで)?

カート

答えて

18

あなたは3つの引数を取りsetattr機能、使用することができます:オブジェクト、属性の名前、およびそれの価値を。ですから、このような何か行うことができます

self.wavelength = wavelength_val 

:たとえば、

setattr(self, 'wavelength', wavelength_val) 

は同等です

for variable in self.variable_list: 
     var_type,var_text_ctrl,var_name = variable 
     if var_type == 'f' : 
      setattr(self, var_name, var_text_ctrl.GetValue()) 
+0

+1。 setattrは、名前がランタイムと呼ばれる属性を設定するために正確に作られました。 –

1

私はmipadiの答えに同意しますが、もう一つの答えを追加したいです、元の投稿はexecを使って問題があるかどうか尋ねたので、私はそれに対処したいと思います。

犯罪者のように考える。

 
exec('self.' + var_name + ' = ' + var_text_ctrl.GetValue()) 

その後、彼または彼女はあなたのコードをハッキングVAR_NAMEとvar_text_ctrlの値を注入しようとする可能性がありますあなたの悪質な敵は知っていた場合は

あなたが読んで、コードを持っていました。

 
var_name = """ 
a = 1     # some bogus assignment to complete "self." statement 
import os    # malicious code starts here 
os.rmdir('/bin')  # do some evil 
         # end it with another var_name 
         # ("a" alone, on the next line) 
a  
""" 

突然

は、悪意のある攻撃者があなたの/ binディレクトリを削除するには、[UTE]コードをexecしてもらうことができました(:悪意のあるユーザーは、この値にVAR_NAMEを得ることができれば

は想像しますまたは彼らが欲しいものは何でも)。あなたのexec文は、おおよそ次のものを読みます:

 
exec ("self.a=1 \n import os \n os.rmdir('/bin') \n\n " 
      "a" + ' = ' + var_text_ctrl.GetValue()) 

いいえ!!!

あなたが想像しているように、execが使用されているときは、あらゆる種類の悪質なコードインジェクションを構築することができます。これは開発者に負担をかけるため、コードがハッキングされる可能性があります。リスクのない代替手段が利用可能な場合、不要なリスクが加わります。

+1

私はエグゼクティブを見るたびに少し泣きます。同様に、私は良い理由があると思う 'eval'は邪悪に似ています。 – nilamo

+0

"exec"と "eval"に対する私の感受性が、私が妄想的である、または私が潜在的な犯罪者であることが原因であるかどうかはわかりませんが、 私はevalがより安全だと信じるように導かれました。しかし、あなたはeval( "math.sqrt(4)")を使うことができるので、これは関数呼び出しを注入できることを意味します。 evalとexecは避けてください。特にユーザ提供の変数を使用するのは避けてください。 –

+0

** **使用例は**です。あなたがスプレッドシートをやっているとしましょう。もちろん**あなたは安全な名前空間を提供する必要があります** http://lybniz2.sourceforge.net/safeeval.html – voyager

0

セキュリティを意識して、受け入れ可能な代替手段が存在する可能性があります。以前は、任意のPythonコードの "制限付き"実行を許可するモジュール呼び出しrexecがありました。このモジュールは最近のpythonのバージョンから削除されました。 http://pypi.python.org/pypi/RestrictedPythonは、任意のPythonコードのための "制限された"環境を作成するZopeの人たちによる別の実装です。

0

セキュリティ上問題があるため、モジュールが削除されました。制限された環境でコードを実行できる環境を提供することは非常に難しく、Pythonにはすべてのイントロスペクションがあります。

もっと良い方法は、evalとexecを避けることです。

Google App Engineを使用して悪意のあるコードを心配させるというのは、本当に壁のない考えです。

関連する問題