"/a" is not "/a" ?

Gary Herron gherron at islandtraining.com
Fri Mar 6 16:08:41 EST 2009


Steven D'Aprano wrote:
> Gary Herron wrote:
>
>   
>> Emanuele D'Arrigo wrote:
>>     
>>> Hi everybody,
>>>
>>> while testing a module today I stumbled on something that I can work
>>> around but I don't quite understand.
>>>   
>>>       
>> *Do NOT use "is" to compare immutable types.*    **Ever! **
>>     
>
> Huh? How am I supposed to compare immutable types for identity then? Your
> bizarre instruction would prohibit:
>
> if something is None
>   

Just use:

  if something == None

It does *exactly* the same thing. 


But...  I'm not (repeat NOT) saying *you* should do it this way.

I am saying that since newbies continually trip over incorrect uses of 
"is", they should be warned against using "is" in any situation until 
they understand the subtle nature or "is". 

If they use a couple "something==None" instead of "something is None"  
in their code while learning Python, it won't hurt, and they can change 
their style when they understand the difference.  And meanwhile they 
will skip  traps newbies fall into when they don't understand these 
things yet.

Gary Herron


> which is the recommended way to compare to None, which is immutable. The
> standard library has *many* identity tests to None.
>
> I would say, *always* use "is" to compare any type whenever you intend to
> compare by *identity* instead of equality. That's what it's for. If you use
> it to test for equality, you're doing it wrong. But in the very rare cases
> where you care about identity (and you almost never do), "is" is the
> correct tool to use.
>
>
>   
>> It is an implementation choice (usually driven by efficiency
>> considerations) to choose when two strings with the same value are stored
>> in memory once or twice.  In order for Python to recognize when a newly
>> created string has the same value as an already existing string, and so
>> use the already existing value, it would need to search *every* existing
>> string whenever a new string is created.
>>     
>
> Not at all. It's quite easy, and efficient. Here's a pure Python string
> constructor that caches strings.
>
> class CachedString(str):
>     _cache = {}
>     def __new__(cls, value):
>         s =  cls._cache.setdefault(value, value)
>         return s
>             
> Python even includes a built-in function to do this: intern(), although I
> believe it has been removed from Python 3.0.
>
>
>   
>> Clearly that's not going to be efficient. 
>>     
>
> Only if you do it the inefficient way.
>
>   
>> However, the C implementation of Python does a limited version 
>> of such a thing -- at least with strings of length 1.
>>     
>
> No, that's not right. The identity test fails for some strings of length
> one.
>
>   
>>>> a = '\n'
>>>> b = '\n'
>>>> len(a) == len(b) == 1
>>>>         
> True
>   
>>>> a is b
>>>>         
> False
>
>
> Clearly, Python doesn't intern all strings of length one. What Python
> actually interns are strings that look like, or could be, identifiers:
>
>   
>>>> a = 'heresareallylongstringthatisjustmade' \
>>>>         
> ... 'upofalphanumericcharacterssuitableforidentifiers123_'
>   
>>>>  
>>>> b = 'heresareallylongstringthatisjustmade' \
>>>>         
> ... 'upofalphanumericcharacterssuitableforidentifiers123_'
>   
>>>> a is b
>>>>         
> True
>
> It also does a similar thing for small integers, currently something
> like -10 through to 256 I believe, although this is an implementation
> detail subject to change.
>
>
>   




More information about the Python-list mailing list