2

我想总结以下代码。它应该做的是检查计算中的变量是否已分配。如果不是,那么结果将为零。因为我有数百个这样的计算,所以我不想重复尝试,除了每个计算。

我怎么能那样做?

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
4

3 回答 3

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.

您可能会受益于使用某种数据结构(例如列表或字典)来包含您的值,而不是将它们存储在单个变量中;然后您可以使用循环来完成所有这些计算,而不是单独编写它们。

于 2013-04-17T23:19:15.077 回答
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这种方式几乎总是表明您之前犯了重大设计错误,正确的做法是备份,直到您发现该错误......</p>


同时,来自评论:

我创建了所有变量的列表,并在它们是否分配了值时遍历它们。如果他们没有,我会将它们设置为浮动('nan')。

没有办法创建变量列表(当然,通过 name off 引用它们除外globals())。您可以创建一个列表,但这对您没有任何好处,因为未定义的变量没有值。

这是另一个迹象,表明您在这里可能想要的不是一堆单独的变量,而是一本字典。

特别是,您可能想要一个defaultdict

variables = collections.defaultdict(lambda: float('nan'))
于 2013-04-18T00:04:48.520 回答
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)
于 2013-04-17T23:31:14.163 回答