10

Can not x and x==None give different answers if x is a class instance ?

I mean how is not x evaluated if x is a class instance ?

SimonT
  • 2,219
  • 1
  • 18
  • 32
Ninja420
  • 3,542
  • 3
  • 22
  • 34

5 Answers5

12

yes it can give different answers.

x == None

will call the __eq__() method to valuate the operator and give the result implemented compared to the None singleton.

not x

will call the __nonzero__() (__bool__() in python3) method to valuate the operator. The interpreter will convert x to a boolean (bool(x)) using the mentioned method and then inverse its returned value because of the not operator.

x is None

means that the reference x points to the None object, which is a singleton of type NoneType and will valuate false in comparaisons. The is operator tests object identity, and thus whether or not the two objects compared are the same instance of an object, and not similar objects.

zmo
  • 24,463
  • 4
  • 54
  • 90
  • 1
    Note that you should not use `x == None`, and should instead use `x is None` – James Jun 22 '13 at 16:44
  • 1
    @Cthulhu `x == None` and `x is None` should never result in different answers. But, since `None` is a singleton instance, it is considered better practice to use `is None`. – arshajii Jun 22 '13 at 16:47
  • 1
    @arshajii `x == None` and `x is None` could return different answers if an implemented object's `__eq__` returns True (for some reason), but the object itself is not `None`. – James Jun 22 '13 at 16:48
  • @Cthulhu Yes, if `x` is an instance of an awful class that defines `__eq__` badly. But arshajii's reason is better. –  Jun 22 '13 at 16:49
  • Yes, *should never* is different than *can never* I suppose. – arshajii Jun 22 '13 at 16:49
5
class A():
    def __eq__(self, other):  #other receives the value None
        print 'inside eq'
        return True
    def __nonzero__(self):    
        print 'inside nonzero'
        return True
...     
>>> x = A()
>>> x == None      #calls __eq__
inside eq
True
>>> not x          #calls __nonzero__
inside nonzero
False

not x is eqivalent to:

not bool(x)

Py 3.x:

>>> class A(object):
        def __eq__(self, other):    #other receives the value None
                print ('inside eq')
                return True
        def __bool__(self):    
                print ('inside bool')
                return True
...     
>>> x = A()
>>> x == None       #calls __eq__
inside eq
True
>>> not x           #calls __bool__ 
inside bool 
False
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
2

Yes; not uses __bool__ (in Python 3; Python 2 uses __nonzero__), and x == None can be overridden by __eq__.

(Both are shown here.)

Ry-
  • 218,210
  • 55
  • 464
  • 476
0

If x is positive the not of it means negative and vice-versa.

x == None means it will only be True if x is None is True else False. Check this.

By positive I mean the if block is chosen. True is also positive.

Community
  • 1
  • 1
Bleeding Fingers
  • 6,993
  • 7
  • 46
  • 74
-1

not x is true for a wide variety of values, e.g. 0, None, "", False, [], {}, etc.

x == None is only true for the one specific value None.

If x is a class instance, then both not x and x == None will be false, but that doesn't mean that those are equivalent expressions.


Fine; that previous paragraph should read:

If x is a class instance, then both not x and x == None will be false unless someone is playing silly buggers with the class definition.

Edward Falk
  • 9,991
  • 11
  • 77
  • 112
  • `If x is a class instance, then both not x and x == None will be false, but that doesn't mean that those are equivalent expressions.` - That is not true at all, class instance can evaluate to both `False` and `None`. – Cthulhu Jun 22 '13 at 16:49
  • When will a class instance evaluate to `None` apart from explicitly assigning `None` to it? You mean, when `__eq__ ()` returns `None`? – thefourtheye Jun 22 '13 at 17:11
  • 1
    Your answer started out well. – dansalmo Jun 22 '13 at 17:39
  • OK, I see from Ashwini's answer above that it is possible to craft a class definition for which "*not x*" is true and "*x == None*" is true, but I don't see how that it serves any useful purpose other than to prove that it's possible. – Edward Falk Jun 23 '13 at 19:59
  • Actually, now that I think about it, I can imagine lots of cases where a class object can be considered to be "zero"; e.g. a numeric class like complex numbers or quaternions. – Edward Falk Jun 24 '13 at 23:21