问题
This is an algorithm in python to validate a day entry. I want to know what does that mean exactly the expression "if day" (semantics). I only know the effect of "if" on boolean expressions not on variables like integers or arrays (I've seen some). Does anyone have an explanation?
def valid_day(day):
if day and day.isdigit():#if day
day = int(day)
if day > 0 and day <= 31:
return day
回答1:
in python, writing
if var:
has the same effect as writing
if bool(var):
(where bool
is the built-in bool
type which also acts as a constructor function for bool objects).
If the value is already a bool (valued True or False) the meaning is clear -- bool(var) returns the same value. For other types, there's almost always a conversion to bool avaliable which depends on the type. For integers (as in C) it's the same as var!=0; for lists or dicts or strings, it's the same as len(var)!=0, and so forth. You can find this in the python docs.
When you define your own class you can define a method via def __nonzero__(self):
, which will be called in this context (when your object is passed to bool
explicitly, or implicitly in an if
-- or while
for that matter).
A notable exception: numpy array objects do not convert to bool (they raise an exception). They need to be explicitly converted using constructs like (arr!=0).any()
or (arr>0).all()
On similar lines: Don't get into the habit of writing any of
if x == True: # This only works as expected when x is a bool
if x is True: # Can be useful but you need to understand what it really means.
if x == None: # Often works as expected, except when it doesn't
Comparison to None should always be done with
if x is None:
(or)
if x is not None:
There is only one None
object, and x is None
will tell you if x refers to that object, and will always give you a bool (True if so, False for any other object). Comparing x==None
(a mistake I frequently made when starting to use Python) will usually work, but it activates the generic comparison machinery of Python, which is not what you probably want; if x
is an instance of a class, the comparison could raise an exception. is
is simple and quick and just does that identity test - it can't be overloaded.
Likewise if x is True
means "if x is the boolean object meaning true, and no other object at all" -- which can be useful, but is too narrow for the case when you are just testing truth value. Somebody might end up passing 1, which will fail an 'is True' test, but otherwise acts very much like True.
回答2:
Behaviour differs a little bit from language to language.
Behaviour 1:
The variable is converted into a boolean. I.e. there are language specific conversions from different types into a boolean. For numeric values, 0
is usually converted into false
while any other value is converted to true
. As far as I know, this is the way Python does it.
Behaviour 2:
Booleans are numeric values. As above, 0
is usually the only value that evaluates to false
Behaviour 3:
Any non-null reference evaluates to true
, null references evaluate to false
.
This should more or less cover it, but there may be other variations or combinations as well, for instance using fallback to method 2 or 3 if 1 is not available. The point is that it's very much a language specific question.
回答3:
The value of the variable is converted to a boolean, i.e. type coercion is performed. How this exactly happens depends on the language. In Python for example, an empty list evaluates to false
. In most languages, 0
evaluates to false
and any other number to true
.
Then of course the variable might already contain a boolean value, e.g.
inBounds = day > 0 and day <= 31
if inBounds:
#...
回答4:
There are lots of answers already that speak in the general term of "What if
does in programming," so let me boil your code out for you.
def valid_day(day):
if day and day.isdigit():#if day
if
signifies the beginning of the if
block, and works as the other answers have pointed out. What follows is the boolean expression day and day.isdigit()
. and
is a Boolean operator that requires both operands (both sides of the equation, in layman's terms) to be True
in order to evaluate as True. In this case, both day
and day.isdigit()
must evaluate to True
for the if
block to run.
In Python, we think of things as "Truthy" and "Falsey." It's easier to define "Truthy" in terms of "Falsey," because the latter is a much shorter list:
None
- 0
- False
- [] "" {} () and the like
Everything else is "Truthy." If you type while -1: print("This loops forever")
it will, in fact, loop forever. All non-zero numbers, all non-empty containers (strings, lists, dicts, sets, tuples, etc), anything not explicitly set to False
or None
will evaluate to True
. In this case, the code is checking to make sure that day
isn't None
, because if it is then day.isdigit()
will throw an AttributeError
and break the code. You can try it yourself: type None.isdigit()
in IDLE. Note that this is likely not the most foolproof implementation, since doing valid_day(31)
will also throw AttributeError
. valid_day
requires a String, even though it's checking numbers.
day = int(day)
if day > 0 and day <= 31:
return day
This is actually repetitive code, since doing int(day)
confirms day.isdigit()
. If this is your code, perhaps consider a try: except block instead, such as:
def valid_day(day):
try: int(day)
except ValueError as e:
return False #this means whatever you passed to it can't be converted
#into an integer: maybe a floating point string?
if day in range(1,32): return True
else: return False
This will let you avoid the trap of checking for everything you know might fail. Instead, check to make sure your checks will be able to run, and let your program handle whatever you pass to it. This will also allow you to design a Day
class that contains more information than an integer but will still return its calendar day using self.__int__(): return self.calendarday
and valid_day(Day())
will return True. In addition, your current code returns None
when you should be returning False
-- as I mentioned above, None
is Falsey, so in most cases this will work (e.g. if not valid_day: do_something_drastic()
) but in some cases you may want to deal with a boolean directly.
Okay, there's a mouthful of words for you.
TL;DR: if
starts the if
block, day and day.isdigit()
is true only when day is a non-empty string that contains an integer, and the rest does what it says it does.
回答5:
if day:
is a short way of writing if day == True:
. When it evaluates the result of True == day
, if day is a simple and basic object such as
integer, then the Python interpreter will try to call the built-in value comparison. If day is a class, the interpreter will call its __nonzero__
member function.
For example
class MyClass:
def __nonzero__(self):
return False
if __name__ == "__main__":
c = MyClass()
if c:
print "yes"
else:
print "No"
回答6:
As others have already provided explanations, I am just going to give some examples to make it clear.
# bool('') is False
if not '':
print('Empty String')
# bool([]) is False
if not []:
print('Empty list')
# bool(None) is False
if not None:
print('None type')
# bool(0) is False
if not 0:
print('Zero Value')
回答7:
I think in python the if condition has two different checks.
- for regular boolean values out of an expression.
- If some thing is 'None'.
Now the current scenario is second style too.
It is checking if day
is None
(to mean nothing, null
).
Your code then is equivalent to
def valid_day(day):
if day is not None and day.isdigit():#if day
day = int(day)
if day > 0 and day <= 31:
return day
This is also a mandatory check to avoid Null access exception
because if some object is None
by way, it will throw exception if we try to access some methods out of that in anticipation that it is not None
.
来源:https://stackoverflow.com/questions/20809417/what-does-it-mean-exactly-if-var-in-python-or-another-languages