0

inspect.getargspec(function).args からの変数名のリストがあります。各リスト項目は、変数名の文字列です。引数変数の値が文字列かどうかを確認できるように、関数内からこれらの文字列名を使用する必要があります。

これが私が取り組んでいるものです

@staticmethod
def boyleslaw(p, V, k):
    """pV = k
    p=pressure Pa, V=volume m^3, k=constant
    substitute letter to solve for that value
    return x"""

    #sv = countvar(gasses.boyleslaw)
    sv = 0
    if p == 'p': sv += 1
    if V == 'V': sv += 1
    if k == 'k': sv += 1
    if sv > 1:
        raise ValueError('Too Many Variables')

    if p == 'p' and sv == 1:
        x = k/V
        return x
    elif V == 'V' and sv == 1:
        x = k/p
        return x
    elif k == 'k' and sv == 1:
        x = p*V
        return x

@staticmethod
def charleslaw(V, T, k):
    """V/T = k
    V=volume m^3, T=temperature K, k=constant
    substitute letter for value to solve for
    return x"""
    #sv = countvar(gasses.charleslaw)
    sv = 0
    if V == 'V': sv += 1
    if T == 'T': sv += 1
    if k == 'k': sv += 1
    if sv > 1:
        raise ValueError('Too Many Variables')

    if V == 'V' and sv == 1:
        x = k*T
        return x
    elif T == 'T' and  sv == 1:
        x = V*k
        return x
    elif k == 'k' and sv == 1:
        x = V/T
        return x

このプロセスをラップしたい

sv = 0
if V == 'V': sv += 1
if T == 'T': sv += 1
if k == 'k': sv += 1
if sv > 1:
    raise ValueError('Too Many Variables')

引数をカウントし、各引数値が文字列であるかどうかを確認する独自のカウント変数関数に入れます。これまでのところ...次に壁+頭...

@staticmethod
def countvar(module):
    """Count number of Variables in args"""
    vc = 0
    alist = inspect.getargspec(module)
    for i in alist.args:
        if isinstance(i, str) == True:
            vc += 1
    return vc

alist.args の各項目は文字列であるため、値に関係なく、いずれかの関数で実行すると 3 が返されます。各変数の VALUE が文字列の場合にのみカウンターをインクリメントし、変数が複数ある場合は ValueError を発生させます。文字列 'p' を変数 p... に変換する方法

編集:明確化

boyleslaw(6886019.02, 1, k) #Solve for k

inspect.getargspec(boyleslaw).args 戻り値['p', 'V', 'k']

リストが欲しい[6886019.02, 1, 'k']

alist[0]= 'p'#文字列名を返す

return p#変数値が必要

値 p が文字列の場合 (呼び出し時に解決する変数が選択された場合)、エラー処理のためにカウンターをインクリメントします

boyleslaw(6886019.02, 1, k)エラーを発生させません

boyleslaw(6886019.02, V, k)だろうraise ValueError('Too Many Variables')

4

3 に答える 3

3

位置引数を使用して関数を定義する場合。各引数は必須になります:

>>> def foo(a, b, c):
...     pass
... 
>>> foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 3 arguments (0 given)

したがって、各引数が渡されたことを確認する必要はありません。これは Python が処理します。

2番目の部分については、あなたが何を望んでいるのか明確ではありません。まず、変数の名前が渡された値と一致するかどうかを確認しますif V == 'V'。次に、2 つの文字列を掛け合わせることができないため、考えていることを行わない式を変数に適用します。

>>> V = 'V'
>>> T = 'T'
>>> k = 'k'
>>> x = k*T
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'str'

したがって、あなたが本当に望んでいると思うのは、数値で計算を試み、それが失敗した場合は適切なエラーを発生させることです。

そのために、これを試すことができます:

try:
   V = int(V)
except ValueError:
   return "Sorry, V must be a number not %s" % V

期待する引数ごとにこのチェックを追加します。これにより、数値のみが得られ、数学的計算が機能することが保証されます。

渡される値の 1 つが float (つまり、小数点付き) でなければならないことがわかっている場合。そうしないとfloat()、別の驚きが得られます。

>>> int('12.4')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '12.4'
>>> float('12.4')
12.4

編集:

あなたの明確化の後、私はあなたが望むのはこれだと思います:

def boyleslaw(variables,solvefor='k'):
    # Normalize stuff
    variables_passed = {k.lower():v for k,v in variables.iteritems()}
    solve_for = k.lower()

    if not len(variables) or len(variables) == 1:
        return "Sorry, you didn't pass enough variables"

    if solve_for in variables_passed:
        return "Can't solve for %s as it was passed in" % solvefor

このメソッドは辞書を変数として受け取ります。デフォルトでは を解きますk。次のように呼び出します。

d = {'V': 12, 't': 45}
boyleslaw(d) # default, solve for k

d = {'t': 45, 'k': 67}
boyleslaw(d,'V') # solve for V

d = {'t':1}
boyeslaw(d) # results in error "Didn't pass enough variables"

d = {'t': 45, 'k': 67}
boyleslaw(d) # results in error "Can't solve for k because k was passed in"    
于 2012-09-08T07:00:11.497 に答える
1

別の解決策は次のとおりです。

def boyleslaw(p=None, V=None, k=None):
    """Given two of the values p, V or k this method
    returns the third according to Boyle's Law."""
    assert (p is None) + (V is None) + (k is None) == 1, \
        "exactly 2 of p, V, k must be given"
    if p is None:
        return 1.0 * k / V
    elif V is None:
        return 1.0 * k / p
    elif k is None:
        return 1.0 * p * V

この関数は、最初に、3 つの数量のうち正確に 2 つが提供されたことをアサートします。次に、3 番目の数量を返します。したがって、どの量を解くかは、与えられた量から明らかであるため、この関数に明示的に指示する必要はありません。

print boyleslaw(p=2, V=3)        # 6.0
print boyleslaw(V=2)             # -> AssertionError
print boyleslaw(p=2, V=3, k=4)   # -> AssertionError
于 2012-09-08T09:33:12.893 に答える
0

あなたが探している機能はexecステートメントだと思います。のようなことができますexec("p='a string'")pこれで、呼び出して期待できるはずです'a string'

于 2012-09-08T06:48:06.997 に答える