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

这在任一函数上运行时都会返回 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'#字符串名称

我需要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 会为您处理这些。

对于您的第二部分,尚不清楚您想要什么。首先,您正在检查变量的名称是否与传递的值匹配if V == 'V',然后对它应用一个不会按照您的想法执行的公式,因为您不能将两个字符串相乘。

>>> 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(),否则你会得到另一个惊喜:

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

这个函数首先断言你已经为它提供了三个数量中的两个。然后它返回第三个数量。所以你不必明确地告诉这个函数要解决哪个数量,因为这从给定的数量中是显而易见的。

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