5

I'm having some trouble with this snippet of code:

if not fundbenchmark.endswith(("Index", "INDEX")) and fundbenchmark is not None:
    fundbenchmark = "%s%s" % (fundbenchmark, " Index")

Traceback:

AttributeError: 'NoneType' object has no attribute 'endswith'

Apparently this error appears when fundbenchmark is None. Implying that there is something wrong with and fundbenchmark is not None:

Am I correct in this assumption or is the explanation to be found elsewhere?

P A N
  • 5,642
  • 15
  • 52
  • 103

3 Answers3

13

The boolean expressions in your if are short-circuit evaluated left to right. What is wrong in your code is that you are applying the is not None condition after you have used the object. You need to invert the order of the conditions.

if fundbenchmark is not None and not fundbenchmark.endswith(("Index", "INDEX")):
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
3

Expressions are evaluated in order. That means the endswith will be called first, before Python has a chance to check if the value is None.

You should swap the order of the checks.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
1

You did the check of None to late.

I would not write an explicit check for None, but use the object itself as boolean expression(See Why is "if not someobj:" better than "if someobj == None:" in Python? for more details about this).

if fundbenchmark and fundbenchmark.endswith(("Index", "INDEX")):
    fundbenchmark = "%s%s" % (fundbenchmark, " Index")
Rudi
  • 19,366
  • 3
  • 55
  • 77
  • 1
    Worth noting that the semantics are a bit different here if f`undbenchmark` is a string or iterable. It evaluates to `False` if empty, not necessarily `None`. But in this case, it works. – juanchopanza Jul 01 '15 at 07:26