With that in mind, the REPL’s treatment of is should make more sense: (Literals are objects that have native Python syntax: numbers, strings, lists that use, etc.) In the case of numbers and strings, literals with the same value become the same object, whether interned or not. When CPython compiles a chunk of code (a “compilation unit”), it has to create objects to represent literals it sees. The results are basically meaningless because of interning! For this reason, absolutely do not use is on the built-in immutable types. The language allows for any immutable object to be interned, but otherwise says nothing. Interning is not strictly part of the language, and other Python implementations may or may not do it. Small integers and some strings are cached: the integer 2 will always refer to the same object, no matter how it comes into existence. So CPython (the canonical Python interpreter, written in C) has a behind-the-scenes optimization called interning. Finding a method on a class would require comparing strings byte-by-byte, and that eats a lot of time. Strictly speaking, every time one of these appears, Python would need to create a new object, and that eats a lot of memory. (One for every constructor, in fact!) There are also a lot of small numbers, like 0 and -1. There are a lot of strings in any given Python program containing, say, _init_. Hang on, what’s going on here? Those are separate numbers and separate strings, and even separate calls to int() why are they claiming to be the same object? The most common by far is for setting default arguments: There are actually very few cases where you want to use is. Note that last step carefully: if neither a nor b overloads =, then a = b is the same as a is b. If any of the special methods return NotImplemented, Python acts as though the method didn’t exist. As a final fallback, Python calls object._eq_(a, b), which is True iff a and b are the same object.If it exists, the objects are equal iff it returns zero. If none of the above are the case, Python repeats the process looking for _cmp_.If type(b) has overridden _eq_, then the result is b._eq_(a).If type(a) has overridden _eq_ (that is, type(a)._eq_ isn’t object._eq_), then the result is a._eq_(b).If type(b) is a new-style class, and type(b) is a subclass of type(a), and type(b) has overridden _eq_, then the result is b._eq_(a).When Python sees a = b, it tries the following. More on why you might care about this below. = on an arbitrary object may be unreliable is never will be. ![]() Hopefully no real code would do such things, but the point is that it can happen. It might randomly decide whether to be equal or not. Both the _eq_ and _cmp_ special methods allow a class to decide for itself what equality means.īecause those methods are regular Python code, they can do anything. There’s another critical, but subtle, difference: = can be overloaded, but is cannot. Did you call SomeClass() twice? Then you have two objects, and a is b will be False. On the other hand, no matter how similar two objects may look or act, is can always tell them apart. What does “the same value” mean? It really depends on the objects’ types usually it means that both objects will respond the same way to the same operations, but ultimately the author of a class gets to decide. is tests whether two objects are the same object.= tests whether two objects have the same value.Some particular quirks of Python’s canon implementation make it difficult to figure out by experimentation, as well. These operators tend to confuse Python newcomers, perhaps because is doesn’t have a clear equivalent in very many other languages.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |