Max Shifrin
Max Shifrin

Reputation: 809

How to force "is not None" test

I have an API in Python which can return an object, or None if no object is found. I want to avoid run-time exceptions/crashes, etc., hence I want to force the users of my API, to do an is not None test.

For example:

x = getObject(...)
if x is not None:
   print x.getName()  #should be o.k.


y = getObject(...)
print y.getName() # print an error to the log

How can I achieve that?

In comparable code in C++, I can add a flag that will be checked when I call the getName(); the flag is set only upon comparing the object to NULL.

In Python, however, I am unable to overload the is operator. Are there any other ways I can achieve that functionality in Python?

Upvotes: 5

Views: 1587

Answers (2)

Tim Ludwinski
Tim Ludwinski

Reputation: 2863

Like it was already said, you can't override is behavior.

To do what you want, basically you can create a surrogate object that has a getName() function. To let the user check if the function failed, you can have the object evaluate to False. (This is a standard practice and I think this is better than making the object equal to None with the __eq__ operator). To do this, you can override override __nonzero__() having it return False.

Example:

class GetObjectFailed(object):
    def __nonzero__():
         return False
    def getName():
         return "An error has occurred" # You could specify a specific error message here...

x = getObject(...)
print x # prints "An error has occurred"
if x:
    # This is the recommended way of doing things
    # Do something with the object
    x.proccess()
if x is not None:
    # This will never work
    x.proccess()
if x != None:
    # This is possible but not recommended
    x.proccess()

Upvotes: 1

Shashank
Shashank

Reputation: 13869

You cannot force the use of if x is not None because you cannot override the behavior of id(). The is operator internally compares the ids of the two objects being compared, and you have no way of controlling that behavior.

However, you can force the use of if x != None or if not x == Noneby overriding the __eq__ and __ne__ methods of your class, respectively.

This is not good practice, however. As @Kevin has noted in the comments, is is the preferred operator to use when comparing to None.

What I would do is write clear and organized documentation for this API, and then clearly warn users that the instantiation could fail and return None. Then, gently nudge users towards good practices by providing an example with the built-in getattr function or an example with the is not None check.

Upvotes: 4

Related Questions