1

この質問の「単位」は、物理量で使用される「測定単位」を指します。

物理量 (「23 kg」など) を含む信頼できないユーザー入力文字列を安全に解析したいと考えています。Python で利用可能なパッケージの 1 つ ( UnumQuantitiesなど) を使用したいのですが、それらは単位間の変換、数式に含まれる単位の簡略化、基本単位への削減を処理するためですが、方法が見つかりませんでした。eval()安全でないと思われるを使用する以外に、文字列を (前述のパッケージの) オブジェクトに変換します。

たとえば、と がUnumパッケージ オブジェクトにバインドされ、キログラムとセンチメートルの単位を参照すると仮定するkgと、次のような文字列からUnumパッケージ オブジェクトを返すことができる関数が必要です。cm

cast_to_unit("100 kg/cm")

また

"100 kg/cm".asUnit()

  1. 上記のパッケージからそのような機能を取得する方法はありますか? そうでない場合は、
  2. 安全に使用する方法はあります eval()か?そうでない場合は、
  3. そのような機能を持つ他のパッケージ (Python でなくても) はありますか?
4

2 に答える 2

5

Unumドキュメントをざっと見てみると、次のようなことができるはずですeval:

from unum.units import * # Load a number of common units.
distance = 100*m
time = eval('9.683*s')
speed = distance / time
print(speed)

evalただし、これを行う場合は、特にこのコードを外部に公開する予定がある場合は、名前空間へのアクセスを制限して安全にするために、ローカルおよびグローバル マッピングを渡す方法についてのドキュメントを必ず読んでください。また、アンダースコア ( ) の文字列をチェックし、_それらを に渡さないようにすることもできevalます。


kindall が指摘したように、*通常、インポートは適切なスタイルではありません。からのインポートを回避する、もう少し安全な代替手段を次に示します*

import unum.units
safe_dict = dict((x,y) for x,y in unum.units.__dict__.items() if '__' not in x)
safe_dict['__builtins__'] = None

def convert(s):
    if '__' in s:
       raise ValueError("Won't do this with underscores...it's unsafe")
    return eval(s,safe_dict)

この投稿__で提唱されている方法を切り取っていることに注意してください

于 2012-11-28T18:40:07.793 に答える
1

:これは決定的な答えではありません。あなたが求めたものに似たものを構築する方法の例としてそれを扱ってください。Unumニーズに合わない場合を除き、モジュールを使用することをお勧めします。

次のように演算子をオーバーロードして、自分で何かを書くことができます。

>>> class Unit(object):
    def __init__(self, unit_name):
        self.unit_name = unit_name
        self.unit_qty = 1
    def __div__(self, other):
        result = self.__class__(self.unit_name)
        result.unit_qty = self.unit_qty / other
        return result
    def __rdiv__(self, other):
        result = self.__class__(self.unit_name)
        result.unit_qty = other / self.unit_qty
        return result
    def __mul__(self, other):
        result = self.__class__(self.unit_name)
        result.unit_qty = self.unit_qty * other
        return result
    def __rmul__(self, other):
        return self.__mul__(other)
    def __repr__(self):
        return '%s %s' % (self.unit_qty, self.unit_name)


>>> kg = Unit('kg')
>>> 100 * kg
100 kg
>>> 100 * 10 * kg
1000 kg
>>> (10 * 20 * kg) / 2
100 kg

eval()次に、式 (" " など) を評価するために使用できます100*kgが、注意が必要です。おそらく、これはいくつかの問題を取り除くのに役立つはずです:

eval('100*kg', {'__builtins__': {}, 'kg': Unit('kg')})
于 2012-11-28T18:46:02.777 に答える