Can I rely on...

Albert Hopkins marduk at letterboxes.org
Thu Mar 19 12:13:33 EDT 2009


On Thu, 2009-03-19 at 08:42 -0700, Emanuele D'Arrigo wrote:
> Hi everybody,
> 
> I just had a bit of a shiver for something I'm doing often in my code
> but that might be based on a wrong assumption on my part. Take the
> following code:
> 
> pattern = "aPattern"
> 
> compiledPatterns = [ ]
> compiledPatterns.append(re.compile(pattern))
> 
> if(re.compile(pattern) in compiledPatterns):
>     print("The compiled pattern is stored.")
> 
> As you can see I'm effectively assuming that every time re.compile()
> is called with the same input pattern it will return the exact same
> object rather than a second, identical, object. In interactive tests
> via python shell this seems to be the case but... can I rely on it -
> always- being the case? Or is it one of those implementation-specific
> issues?
> 
> And what about any other function or class/method? Is there a way to
> discriminate between methods and functions that when invoked twice
> with the same arguments will return the same object and those that in
> the same circumstances will return two identical objects?
> 
> If the answer is no, am I right to state the in the case portrayed
> above the only way to be safe is to use the following code instead?
> 
> for item in compiledPatterns:
>    if(item.pattern == pattern):

In general, no.  You cannot rely on objects instantiated with the same
parameters to be equal. Eg.:

        >>> class N(object):
        	def __init__(self, foo):
        		self.foo = foo
        
        >>> a = N('m')
        >>> b = N('m')
        >>> a == b
        False
        
        If, however, the designer of the class implements it as such
        (and documents it as well) then you can. E.g:
        
        >>> del N
        >>> class N(object):
        	def __init__(self, foo):
        		self.foo = foo
        	def __eq__(self, other):
        		return self.foo == other.foo
        
        >>> a = N('m')
        >>> b = N('m')
        >>> a == b
        True

For functions/methods it really depends on the implementation.  For
example, do we *really* want the following to always be true? Even
though we passed the same arguments?

        >>> import random
        >>> random.randint(0, 10) == random.randint(0, 10)

For the re module, unless it's documented that 

        >>> re.compile(p) == re.compile(p)

is always true then you should not rely on it, because it's an
implementation detail that may change in the future.





More information about the Python-list mailing list