可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
False
is equivalent to 0
and True
is equivalent 1
so it\'s possible to do something like this:
def bool_to_str(value):
\"\"\"value should be a bool\"\"\"
return [\'No\', \'Yes\'][value]
bool_to_str(True)
Notice how value is bool
but is used as an int
.
Is this this kind of use Pythonic or should it be avoided?
回答1:
I\'ll be the odd voice out (since all answers are decrying the use of the fact that False == 0
and True == 1
, as the language guarantees) as I claim that the use of this fact to simplify your code is perfectly fine.
Historically, logical true/false operations tended to simply use 0
for false and 1
for true; in the course of Python 2.2\'s life-cycle, Guido noticed that too many modules started with assignments such as false = 0; true = 1
and this produced boilerplate and useless variation (the latter because the capitalization of true and false was all over the place -- some used all-caps, some all-lowercase, some cap-initial) and so introduced the bool
subclass of int
and its True
and False
constants.
There was quite some pushback at the time since many of us feared that the new type and constants would be used by Python newbies to restrict the language\'s abilities, but Guido was adamant that we were just being pessimistic: nobody would ever understand Python so badly, for example, as to avoid the perfectly natural use of False
and True
as list indices, or in a summation, or other such perfectly clear and useful idioms.
The answers to this thread prove we were right: as we feared, a total misunderstanding of the roles of this type and constants has emerged, and people are avoiding, and, worse!, urging others to avoid, perfectly natural Python constructs in favor of useless gyrations.
Fighting against the tide of such misunderstanding, I urge everybody to use Python as Python, not trying to force it into the mold of other languages whose functionality and preferred style are quite different. In Python, True and False are 99.9% like 1 and 0, differing exclusively in their str(...)
(and thereby repr(...)
) form -- for every other operation except stringification, just feel free to use them without contortions. That goes for indexing, arithmetic, bit operations, etc, etc, etc.
回答2:
I\'m with Alex. False==0
and True==1
, and there\'s nothing wrong with that.
Still, in Python 2.5 and later I\'d write the answer to this particular question using Python\'s conditional expression:
def bool_to_str(value):
return \'Yes\' if value else \'No\'
That way there\'s no requirement that the argument is actually a bool -- just as if x: ...
accepts any type for x
, the bool_to_str()
function should do the right thing when it is passed None, a string, a list, or 3.14.
回答3:
surely:
def bool_to_str(value):
\"value should be a bool\"
return \'Yes\' if value else \'No\'
is more readable.
回答4:
Your code seems inaccurate in some cases:
>>> def bool_to_str(value):
... \"\"\"value should be a bool\"\"\"
... return [\'No\', \'Yes\'][value]
...
>>> bool_to_str(-2)
\'No\'
And I recommend you to use just the conditional operator for readability:
def bool_to_str(value):
\"\"\"value should be a bool\"\"\"
return \"Yes\" if value else \"No\"
回答5:
It is actually a feature of the language that False == 0 and True == 1 (it does not depend on the implementation): Is False == 0 and True == 1 in Python an implementation detail or is it guaranteed by the language?
However, I do agree with most of the other answers: there are more readable ways of obtaining the same result as [\'No\', \'Yes\'][value]
, through the use of the … if value else …
or of a dictionary, which have the respective advantages of hinting and stating that value
is a boolean.
Plus, the … if value else …
follows the usual convention that non-0 is True: it also works even when value == -2
(value is True), as hinted by dahlia. The list and dict approaches are not as robust, in this case, so I would not recommend them.
回答6:
Using a bool as an int is quite OK because bool is s subclass of int.
>>> isinstance(True, int)
True
>>> isinstance(False, int)
True
About your code: Putting it in a one-line function like that is over the top. Readers need to find your function source or docs and read it (the name of the function doesn\'t tell you much). This interrupts the flow. Just put it inline and don\'t use a list (built at run time), use a tuple (built at compile time if the values are constants). Example:
print foo, bar, num_things, (\"OK\", \"Too many!)[num_things > max_things]
回答7:
Personally I think it depends on how do you want to use this fact, here are two examples
Just simply use boolean as conditional statement is fine. People do this all the time.
a = 0
if a:
do something
However say you want to count how many items has succeed, the code maybe not very friendly for other people to read.
def succeed(val):
if do_something(val):
return True
else:
return False
count = 0
values = [some values to process]
for val in values:
count += succeed(val)
But I do see the production code look like this.
all_successful = all([succeed(val) for val in values])
at_least_one_successful = any([succeed(val) for val in values])
total_number_of_successful = sum([succeed(val) for val in values])