让Python的布尔值打印“On”或“Off”,而不是“True”或“False”

6
什么是使变量的行为像布尔值但打印 "On" 或 "Off" 而不是 "True" 或 "False" 的最佳方法?目前程序输出: "Color: True",而 "Color: On" 更有意义。
记录一下,我最初尝试创建一个从 "bool" 继承的 "OnOff" 类:
class OnOff(bool):
    def __str__(self):
        if self: return 'On'
        else: return 'Off'

从评论中,我现在理解bool是一个单例,这就是为什么它失败惨了:

Traceback (most recent call last):
    class OnOff(bool):
TypeError: Error when calling the metaclass bases
    type 'bool' is not an acceptable base type

3
@Josh:这不是“帮我做作业.com”。请发布你尝试过的代码,以便我们可以看到你的理解水平。 - S.Lott
1
@S.Lott:这不是作业,正如我所说的,我没有任何与问题本身相关的代码。如果你一定要看到一些代码,请点击这里 - Zaz
1
@Josh:尝试解决问题并发布您尝试过的代码会非常有帮助。真的很有帮助。我们对“请为我编写此代码”这类问题持谨慎态度。 - S.Lott
1
@S.Lott:如果我有任何代码,我会发布它的,只是因为我是 OOP 的新手,在这种情况下我甚至不知道如何开始。我尝试创建一个从 bool 继承的类,但它失败了 - 你是说我应该发布那段代码? - Zaz
我已经删除了我最初编写的代码,但是我从记忆中将其添加到了问题中。 - Zaz
显示剩余2条评论
12个回答

19

print ("关闭", "开启")[value] 也可以使用(因为(False, True) == (0,1)


10
def Color(object):

    def __init__(self, color_value=False):
        self.color_value = color_value

    def __str__(self):
       if self.color_value:
          return 'On'
       else:
          return 'Off'

    def __cmp__(self, other):
        return self.color_value.__cmp__(other.color_value)

尽管这可能对你来说有些过头。 :)


这是迄今为止最好的解决方案,但那个类根本不会像普通的布尔值一样工作。 - Zaz
2
实际上,__nonzero__ 钩子实现了真值测试。 - miku
1
似乎那不是正确的做法。颜色与<code>bool</code>类型无关。对我来说,组合优于继承,因为它可以提供更大的控制力。 - Rahul
1
如果Color不需要与bool类型有所不同,那么这个答案就过度了。@Josh,如果我理解正确,你关心的是表现,而不是内部表示操作。在内部,你希望它是一个布尔值,对吗?如果你只关心表现,那么你可以使用除str()之外的其他函数将bool转换为str,比如说['关闭', '开启'][my_bool_value] - Mike DeSimone
@Mike:对我来说不太实际,我已经更新了第一篇帖子并解释了原因。 - Zaz
显示剩余3条评论

6

我最喜欢的技巧是使用布尔值来索引数组:

return "Color: {0}".format(['Off','On'][has_color])

需要注意的是,该值必须为FalseTrue01。如果您有其他值,则必须先将其转换为布尔值。


一个元组 ('Off','On')[has_color] 不是更高效吗? - Zaz
@Josh:老实说,我不知道。唯一可以确定的区别是列表是可变的,而元组是不可变的,在这里并不重要。如果我没记错的话,列表是创建的。 - Mike DeSimone

4
print "On" if color else "Off"    # Python 2.x
print ("On" if color else "Off")  # Python 3.x

打印语句位于循环外部变量的类中,因此这并不是非常实用。 - Zaz

3

True和False是单例对象。Python中只有一个True对象和一个False对象,因此尝试从它们继承会引起问题(它们不是用于这种方式的)。

你不能重载逻辑and/or操作符,这将防止你创建一个真正的布尔对象。它将不断地回到Python的bool类型。

因此:不要这样做。

如果您不希望您的值打印为True和False,请不要直接调用print。print用于快速和脏的输出。如果您需要更多内容,则需要进行更多工作。在这种情况下,您只需要使用ToOnOff函数即可。


1

我现在正在使用基于 Rahul's code的这个解决方案:

class OnOff(object):
    def __init__(self, value):
        self._value = value

    def __str__(self):
       if self._value: return 'On'
       else: return 'Off'

    def __cmp__(self, other):
        return self._value.__cmp__(other)

我修改了__cmp__函数,使对象能够与布尔值进行比较,并且还更改了一些其他小的东西。全部功劳归Rahul所有。


这是我最终使用的代码。尽管如此,我认为Rahul的代码值得点赞。 - Zaz
实际上,我改变了主意,我找到了一种不需要创建类的方法来完成这个。 - Zaz

0

很遗憾你不能这样做:True.__str__=lambda:"On"

不幸的是,它会抱怨只读。无论如何,那将是一种非常hackish的方法!


0

试试这个好奇的:

a = True
b = False
print a and 'On' or 'Off'
print b and 'On' or 'Off'

0
mybool = {True: 'On', False: 'Off'}
mybool[True] == 'On'
mybool[False] == 'Off'

0

如果你不想与 print 搞砸的话...

class BoolHack(object):
    def __init__(self):
        from sys import stdout
        self.realout = stdout

    def write(self, text):
        if text == 'False':
            text = 'Off'
        elif text == 'True':
            text = 'On'
        self.realout.write(text)

import sys

sys.stdout = BoolHack()

print "Hello world" # ==> Hello world
print 1             # ==> 1
print True, 10      # ==> On 10
print False         # ==> Off
print "True hack"   # ==> True hack

警告:不要在真实生产代码中使用!这只是为了使您的答案集完整。

print 调用对象的 str() 方法进行打印,然后将字符串放入 stdout 中... 因此您无法检查对象的类型。但是,仅仅将“False”或“True”打印成一个单独的字符串相当罕见,因此在您非常特定的情况下可能会起作用。


你为什么要给人们提供这样糟糕的想法! - Winston Ewert
1
@Winston Ewert:即使是最简陋的黑客技巧有时也很有用。 - liori

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接