views:

49

answers:

3

I'm running a small app on Google App Engine with Python. In the model I have property of of type DateTimeProperty, which is datetime.datetime. When it's created there is no value, None. I want compare if that datetime.datetime is None, but I can't.

if object.updated_date is None or object.updated_date >= past:
  object.updated_date = now

Both updated_date and past is datetime.datetime.

I get the following error.

TypeError: can't compare datetime.datetime to NoneType

What is the correct way to do this?

+2  A: 

You want and, not or.

You may also want to use is None.

EDIT:

Since you've determined that object.updated_date isn't None, this only other possibility is that past is None.

Ignacio Vazquez-Abrams
+3  A: 

Perhaps you mean:

if object.updated_date and object.updated_date >= past:

If it's truthy (which implies not null), we check that it's also >= past. This uses short-circuit evaluation, which means the second condition isn't checked if the first is falsy.

Matthew Flaschen
It doesn't check nullness, it checks falseness. This will catch `None`, but it will also catch some non-`None` values as well.
Ignacio Vazquez-Abrams
True, @Ignacio. I've clarified now.
Matthew Flaschen
+2  A: 

Given that the previous discussion seems to have established that either of the variables could be None, one approach would be (assuming you want to set object.updated_date when either of the variables is None):

if None in (past, object.updated_date) or object.updated_date >= past:
  object.updated_date = now

point being that the check None in (past, object.updated_date) may be handier than the semantically equivalent alternative (past is None or object.update_date is None) (arguably an epsilon more readable thanks to its better compactness, but it is, of course, an arguable matter of style).

As an aside, and a less-arguable matter of style;-), I strongly recommend against using built-ins' names as names for your own variables (and functions, etc) -- object is such a built-in name which in this context is clearly being used for your own purposes. Using obj instead is more concise, still readable (arguably more so;-), and has no downside. You're unlikely to be "bitten" in any given case by the iffy practice of "shadowing" built-ins' names with your own, but eventually it will happen (as you happen to need the normal meaning of the shadowed name during some later ordinary maintenance operation) and you may be in for a confusing debugging situation then; meanwhile, you risk confusing other readers / maintainers... and are getting absolutely no advantage in return for these disadvantages.

I realize that many of Python's built-ins' names are an "attractive nuisance" in this sense... file, object, list, dict, set, min, max... all apparently attractive name for "a file", "an object", "a list`, etc. But, it's worthwhile to learn to resist this particular temptation!-)

Alex Martelli