-1

I have this code in a decorator:

is_local_valid = ['system_id', 'server_id', 'sensor_id']
local_params = [x for x in is_local_valid if x in kwargs.keys() and kwargs[x].lower() is 'local'] + [y for y in args if y.lower() is 'local']
if local_params == []:
    raise AssertionError("Tried to access the database from a non connected profile")

I noticed that the is infix operator for comparing two strings returns False in this case, even when kwargs[x].lower() equals to local. The == operator does return True, though. Both are str, of course.

Any clue on what's going on?

joaquin
  • 82,968
  • 29
  • 138
  • 152
Manuel Abeledo
  • 327
  • 2
  • 4
  • 14

2 Answers2

3

The operators is and is not test for object identity:
x is y is true if and only if x and y are the same object. x is not y yields the inverse truth value.

>>> id('local')
42745112
>>> a = {1: 'locAl'}
>>> id(a[1].lower())
53363408

They are not the same object

laike9m
  • 18,344
  • 20
  • 107
  • 140
  • Well, that's very 'user friendly', as the Python interpreter optimizes the use of strings by avoiding unnecesary copies only and if only they're not a product of a method. – Manuel Abeledo Apr 10 '14 at 11:15
  • @ManuelAbeledo Yes. Actually to fully understand this you should read articles about Python **Data Model**, and learn about `reference counting`. – laike9m Apr 10 '14 at 11:22
0

a is b determines whether two names a and b reference the same object (i.e. id(a) == id(b)). a == b determines whether they have equal values. It is rarely a good idea to compare strings with is; use == instead:

>>> "".join("hello")
'hello'
>>> "hello" is "".join("hello")
False
>>> "hello" == "".join("hello")
True

The only general case for comparison with is would be for None, e.g.:

if a is None:
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437