如何在if语句中简化布尔逻辑?

时间:2014-06-26 05:07:43

标签: python python-2.7

我有4个变量,其中一些变为True和False,对于每个组合,我将不得不调用一个或几个函数。 我目前正在为每个案例使用if else语句,我想知道是否有更好的方法来获得与字典或其他内容相同的结果。

谢谢

这是我的代码:

    if (self.cpe_ip and self.cpe_passwd) and self.phone and self.pppoe:
        print "launch ISP portal, modem and radius"
        if self.isp() == "east":
            self.launchbell()
        else:
            self.launchtelus()
        print 'check modem...'
        self.modemstatus()
        radius = sgp_radius.Radius(self.pppoe)
        print 'check radius logs...'
        self.data = radius.sgp()

        self.radius_save()

        #exit(0)
    elif (self.cpe_ip and self.cpe_passwd) and not self.phone and not self.pppoe:
        print "launch modem test only"
        self.modemstatus()


        #exit(0)
    elif not(self.cpe_ip and self.cpe_passwd) and self.phone and not self.pppoe:
        #print "only  Bell portal"
        if self.isp() == "east":
            self.launchbell()
        else:
            self.launchtelus()

    elif (self.cpe_ip and self.cpe_passwd) and not self.phone and self.pppoe:
        #print "launch modem and radius test."
        self.modemstatus()

        radius = sgp_radius.Radius(self.pppoe)
        print 'check radius logs...'
        self.data = radius.sgp()
        self.radius_save()

    elif not(self.cpe_ip and self.cpe_passwd) and not self.phone and self.pppoe:
        #print "only radius tests."
        radius = sgp_radius.Radius(self.pppoe)
        self.data = radius.sgp()

        self.radius_save()

    elif not(self.cpe_ip and self.cpe_passwd) and self.phone and self.pppoe:
        print "bell and radius tests."
        if self.isp() == "east":
            self.launchbell()
        else:
            self.launchtelus()

        radius = sgp_radius.Radius(self.pppoe)
        print 'check radius logs...'
        self.data = radius.sgp()
        self.radius_save()

    elif (self.cpe_ip and self.cpe_passwd) and self.phone and not self.pppoe:
        #print "launch modem and bell tests."
        if self.isp() == "east":
            self.launchbell()
        else:
            self.launchtelus()
        self.modemstatus()

    else:
        #print "test bell only"
        #launchbell(self.phone)
        exit(0)

2 个答案:

答案 0 :(得分:5)

简化它的一种方法是识别和分解重复:

if self.phone:
    if self.isp() == "east":
        self.launchbell()
    else:
        self.launchtelus()

if self.cpe_ip and self.cpe_passwd:
    print 'check modem...'
    self.modemstatus()

if self.pppoe:
    radius = sgp_radius.Radius(self.pppoe)
    print 'check radius logs...'
    self.data = radius.sgp()
    self.radius_save()

答案 1 :(得分:2)

你在问题​​中暗示,逻辑的某种查找表可能是要走的路,你可以用很多方法做出类似的事情。

正如你所说的,有一种方法可以用dict,如下所示。

这种方式导致代码看起来比看上去更复杂的代码更简单,并简化和分解复制"针对您的特定示例的解决方案,但是这种方法更容易扩展到针对不同情况有更多不同逻辑的情况......我不是说它更好" ......只是一个不同的选择!

def launch_isp_portal_and_radius():
   print "launch ISP portal, modem and radius"
   # etc

# etc

DecisionTable = {
 # cpe_ip cpe_passwd phone ppoe
   (True,  True,  True,  True ) : launch_isp_portal_and_radius,
   (True,  True,  False, False) : launch_modem_test_only,
   (False, False, True,  False) : only_Bell_portal,
   (False, True,  True,  False) : only_Bell_portal,
   (True,  False, True,  False) : only_Bell_portal,
   (True,  True,  False, True ) : launch_modem_and_radius_test,
   (False, False, False, False) : only_radius_tests,
   (False, True,  False, False) : only_radius_tests,
   (True,  False, False, False) : only_radius_tests,
   (False, False, True,  True ) : bell_and_radius_tests
   (False, True,  True,  True ) : bell_and_radius_tests,
   (True,  False, True,  True ) : bell_and_radius_tests,
   (True,  True,  True,  False) : launch_modem_and_bell_tests
}

action = DecisionTable.get((self.cpe_ip, self.cpe_passwd, self.phone, self.ppoe))

if action:
   action()
else:
   raise StandardError("Whoa, internal logic error!")

(当然还有其他方法来制作决策表 - 数组是另一个明显的选择。数组的问题是使它的静态声明对于它所代表的逻辑看起来是可读的......)

(编辑:按照jons的建议将dict索引在元组上)

相关问题