Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In python, how does one test if a string-like object is mutable?

Tags:

python

I have a function that takes a string-like argument.

I want to decide if I can safely store the argument and be sure that it won't change. So I'd like to test if it's mutable, e.g the result of a buffer() built from an array.array(), or not.

Currently I use:

type(s) == str

Is there a better way to do it?

(copying the argument is too costly, that's why I want to avoid it)

like image 618
tonfa Avatar asked Sep 03 '09 21:09

tonfa


4 Answers

It would be better to use

isinstance(s, basestring)

It works for Unicode strings too.

like image 135
Bastien Léonard Avatar answered Oct 11 '22 14:10

Bastien Léonard


If it's just a heuristic for your caching, just use whatever works. isinstance(x, str), for example, almost exactly like now. (Given you want to decide whether to cache or not; a False-bearing test just means a cache miss, you don't do anything wrong.)


(Remark: It turns out that buffer objects are hashable, even though their string representation may change under your feet; The hash discussion below is interesting, but is not the pure solution it was intended to be.)

However, well implemented classes should have instances being hashable if they are immutable and not if they are mutable. A general test would be to hash your object and test for success.

>>> hash({})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: dict objects are unhashable

This will give false positives I'm sure, but mutable objects being hashable is strictly an interface break; I would expect python library types to obey this interface, a test of a small sample gives correct answers:

hashabe: str (Immutable), buffer (Warning, immutable slice of (possibly) mutable object!)
unhashable: list, array.array
like image 33
u0b34a0f6ae Avatar answered Oct 11 '22 15:10

u0b34a0f6ae


Just use duck typing -- remember, it's "Easier to Ask for Forgiveness Than Permission". Try to mutate the string-like object, and be prepared to catch an exception if you can't.

like image 42
Daniel Pryden Avatar answered Oct 11 '22 14:10

Daniel Pryden


I'd just convert it to an immutable string:

>>> s1 = "possibly mutable"
>>> 
>>> s2 = str(s1)
>>> s1 is s2
True

In case s1 is immutable the same object is given back, resulting in no memory overhead. If it's mutable a copy is being made.

like image 34
Georg Schölly Avatar answered Oct 11 '22 14:10

Georg Schölly