3

我的情况是:

  1. 函数内容在评估之前在字符串中动态创建,
  2. 我不想使用if test: dosomething else: dosomethingElse来编写内容,因为用户可以更改部分字符串内容,并且我不希望他们必须在条件语句中管理数学表达式之间的空格。

所以,我使用以下列表提示:[dosomethingElse, dosomething][ test ],(测试的真/假答案给了我做某事/做某事)。

该解决方案工作正常,但 dosomething 和 dosomethingElse在测试检查之前进行了评估,我只对评估一个感兴趣。(我处于严重的时间限制情况)。

有没有办法在一行中只评估一个函数?

这里,代码的主要步骤。这里列出了“依赖项”,但它们在原始程序中得到了很好的管理。

  1. 创建唯一的 fun_id

    def gen_id():
        s = 10000
        while s:
            yield s
            s += 1
    
    fun_ticket = gen_id()
    
  2. 有趣的描述(名称、参数、表达式、id)

    from collections import defaultdict
    d= defaultdict(lambda :defaultdict())
    
    d["dosomething"]["args"] = set(["argA","argB"])
    d["dosomething"]["exp"] = "return argA + argB"
    d["dosomething"]["id"] = "f_%d"%(fun_ticket.next())
    
    d["dosomethingElse"]["args"] = set(["argX","argY","argZ"])
    d["dosomethingElse"]["exp"] = "return argX + argY+ argZ"
    d["dosomethingElse"]["id"] = "f_%d"%(fun_ticket.next())
    
    d["doChoice"]["args"] = set(["argE","argF"])
    d["doChoice"]["exp"] = "return [dosomethingElse, dosomething][argE > 0] + argF"
    d["doChoice"]["id"] = "f_%d"%(fun_ticket.next())
    
  3. 准备要评估的 doChoice 函数。

    dependencies =  ('dosomething', 'dosomethingElse', 'doChoice')
    Allargs = set().union(*[d[x]["args"] for x in dependencies])
    
    
    funChoice = 'def %s(%s): %s'%(d['doChoice']['id'],",".join(Allargs),d['doChoice']["exp"])
    
  4. 结果: funChoice 字符串为:

    def f_10002(argX,argY,argZ,argA,argB,argE,argF): return [f_10001(argX,argY,argZ), f_10000(argA,argB)][argE > 0] + argF
    

这就是问题所在:funChoice 评估 eval doSomething AND doSomethingElse。有没有办法只评估一个而不使用 if else (以及字符串中的空间管理问题..)?

4

1 回答 1

2

使用条件表达式

dosomething if test else dosomethingelse

只有dosomething和之一dosomethingelse将根据 的结果进行评估test。引用文档:

该表达式x if C else y首先评估条件C (不是 x );如果C为真,则计算x并返回其值;否则,评估y并返回其值。

将此适应您的代码:

d["doChoice"]["exp"] = "return (dosomething if argE > 0 else dosomethingElse) + argF"
于 2013-08-08T09:20:36.890 回答