我想总结一下以下代码。它应该做的是检查计算中的变量是否已分配。如果不是,那么结果将为零。因为我有数百个这样的计算,所以我不想重复尝试 - 除了每次计算。
我怎么能这样做?
a = 1
b = 2
d = 3
f = 2
try:
ab = a + b
except:
ab = 0
try:
ac = a - c
except:
ac = 0
try:
bg = b / g
except:
ac = 0
答案 0 :(得分:5)
编写一个函数来执行此操作,使用lambda
(单行函数)推迟对变量的评估,以防其中一个变量存在:
def call_with_default(func, default):
try:
return func()
except NameError: # for names that don't exist
return default
ab = call_with_default(lambda: a+b, 0)
# etc.
通过使用某种数据结构(例如列表或字典)来包含您的值而不是将它们存储在单个变量中,您可能会受益;然后你可以使用循环来完成所有这些计算,而不是单独编写它们。
答案 1 :(得分:3)
如果你有一堆甚至可能没有定义的变量,你可能真的没有一堆变量。
例如,如果您正在尝试构建一个交互式解释器,用户可以在其中创建新变量,请不要尝试将每个用户变量保存为同名的全局变量(如果除了安全之外没有其他原因) - 如果用户尝试创建名为main
的变量并删除main
函数,会发生什么?)。存储用户变量字典。
一旦你这样做,Alexey和kindall建议的解决方案将起作用:
def add_default(first, second, default):
try:
return variables[first] + variables[second]
except KeyError:
return default
variables['ab'] = add_default('a', 'b', 0)
如果您确实需要在同一级别混合代码和用户代码,那么可以执行此操作,方法是使用globals()
本身作为您的字典:
def add_default(first, second, default):
try:
return globals()[first] + globals()[second]
except KeyError:
return default
ab = add_default('a', 'b', 0)
然而,使用globals
这种方式几乎总是表明您之前已经出现了重大设计错误,并且正确的做法是备份,直到您发现错误...
同时,来自评论:
我创建了一个包含所有变量的列表,如果它们分配了值,则循环遍历它们。如果他们没有,我会将它们设置为浮动('nan')。
无法创建变量列表(当然,除了通过名称globals()
引用它们之外)。您可以创建值的列表,但这对您没有任何好处,因为没有未定义变量的值。
这是另一个迹象,你在这里想要的不是一堆单独的变量,而是一本字典。
特别是,您可能需要defaultdict
:
variables = collections.defaultdict(lambda: float('nan'))
答案 2 :(得分:1)
对于更通用的情况,您可以使用lambdas(虽然不是太优雅的解决方案):
def lambda_default(func, default, *args):
try:
return func(*args)
except:
return default
abc = lambda_default(lambda x, y: x + y * z, 0, a, b, c)
如果你有一些常用功能,你可以将它们再包装成一个def
,当然:
def add_default(first, second, default):
return lambda_default(operator.add, 0, first, second)
ab = add_default(a, b, 0)