开发者

Make Python bool print 'On' or 'Off' rather than 'True' or 'False'

What is the best way to make a variable that works exactly like a bool but prints On or Off rather than True or False? Currently the program is printing: Color: True, whereas Color: On would make more sense.

For the record, I initially tried to make an OnOff class that inherits from bool:

class OnOff(bool):
    def __str__(self):
        if self: return 'On'
        else: return 'Off'

From the comments, I now understand that bool is a singleton, which is why this faile开发者_JS百科d miserably:

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


print ("Off", "On")[value] works too (because (False, True) == (0,1))


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)

Although this could be overkill for you. :)


My favorite trick is to use the bool to index an array:

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

The caveat is that the value has to be False, True, 0, or 1. If you have something else, then you have to convert it to boolean first.


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


True and False are singletons. There is only one True and one False object in python. As a result attempting to inherit from them causes issues. (They just were not meant to be used in that way).

You cannot overload the logical and/or operations which will prevent you from creating a really bool-like object. It'll constantly revert back to python's bool.

So: Don't.

If you don't want your values to print as True and False, don't call print on them directly. Print is for quick and dirty output. If you want something more then it gives then you'll need to do more work. In this case, all you need is to ToOnOff function.


I am now using this solution based off 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)

I changed the __cmp__ function to enable the object to compare to bools and also changed some other minor stuff. Full credit to Rahul.


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


If you don't want to mess with 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

WARNING: Do not use in real production code! This is only for making your set of answers complete.

print calls str() on objects to print, and only then puts the string to stdout... so you cant check type of object. But it is quite rare to just print 'False' or 'True' as a single string, so in your very very specific case it might work.


class Color:
    def __init__(self,C):
    if C==True:
        self.col='On'
    else:
        self.col='Off'

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


Pity you can't do True.__str__=lambda:"On"

Unfortunately it complains it is read-only. Anyway, that would be a VERY hackish way to do it!


Try this curious one:

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


Taking the advice of the public, I've changed my mind and found a better way to solve my problem than by creating a class: Convert the menu items to strings outside the class. Allowing me to use the solution proposed by THC4k.

Unidiff:

         menu.items=((
             ('Play Game', True),
             '  ',
             'Speed: ', (speed, True),
             '  ',
             'Screen: ', (screen_width, True), 'x', (screen_height, True),
             '  ',
-            'Color: ', (color, True),
+            'Color: ', (("Off", "On")[color], True),
             '  ',
             ('Exit', True)
         ))

(I did the same for the other variables, I'm just trying to be succinct with the diff)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜