None is a keyword used to represent a Null value, Object, or No value at all.
None has the NoneType datatype, and actually is the only "object" that can have that datatype. You can not create other NoneType objects.
None is not the same as False, 0, or an empty string. When comparing objects to None it will return False for anything other than None.
Python, and Jython by extension, are not Strongly Typed languages (meaning you, the programmer, declare the type of the object). Instead they work on a concept known as duck typing.
Think of it like this "If it looks like a duck and it acts like a duck, it is a duck." In a similar way "if it looks like an integer and it acts like and integer it is an integer".
So user_id assumes the type of the return value of system.db.runNamedQuery(). If that value is an integer then user_id is an integer, if the value is NoneType then user_id is NoneType.
This is why your conditional statement works, because it will return true, if and only if User_Id is None.
So, why all the confusion about what None is? Well, because, there is a little hiccup in the way None works.
A class is free to implement comparison any way it chooses, and it can choose to make comparison against None mean something.
Reference here.
Same is true for functions. So when you print(None) the function "decides" that what you meant was actually something more like print(""). And if a function is expecting an Integer it may choose to treat None as zero.
The most pythonic way to write this is actually to use the "is not" comparison.
userID = system.db.runNamedQuery(“username_select_index”, {“name” :name})
if userID Is Not None:
system.db.runNamedQuery(“username_update”, {“name”:name})