Python - 如何将字符串'p'从列表转换为变量值p

时间:2012-09-08 06:41:52

标签: python python-2.7

我有来自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')

进入它自己的计数变量函数来计算参数并检查每个参数Value是否为字符串。我到底要做什么...然后墙壁+头......

@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

当在任一函数上运行时返回3,无论它们的值如何,因为alist.args中的每个项都是一个字符串。我只想增加计数器,如果每个变量的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' #string name

我需要return p #variable value

如果值p是一个字符串(在调用时选择哪个变量来解决),则增加计数器以进行错误处理

boyleslaw(6886019.02, 1, k)不会引发错误

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

3 个答案:

答案 0 :(得分: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将为您处理此事。

对于你的第二部分,目前尚不清楚你想要什么。首先,您正在检查变量的名称是否与传递的值if V == 'V'相匹配,然后您应用一个不符合您想象的公式,因为您不能将两个字符串相乘。< / p>

>>> 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

为您期望的每个参数添加此检查。这将确保您只有数字,然后您可以使用数学计算。

如果您知道传入的值之一必须是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"    

答案 1 :(得分: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

此函数首先断言您已经为它提供了三个量中的两个。然后它返回第三个数量。因此,您不必明确告诉此函数要解决的数量,因为从给定数量可以看出这一点。

print boyleslaw(p=2, V=3)        # 6.0
print boyleslaw(V=2)             # -> AssertionError
print boyleslaw(p=2, V=3, k=4)   # -> AssertionError

答案 2 :(得分:0)

我认为您正在寻找的功能是exec语句。您可以执行exec("p='a string'")之类的操作。您现在应该可以致电p并期待'a string'