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