6

I recently discovered abstract base classes (ABCs) in collections and like their clear, systematic approach and Mixins. Now I also want to create customs strings (*), but I couldn't find an ABC for strings.

There is UserString, but UserDict was discouraged!? Deriving from str itself would have no Mixins? How would you access the "data" part of the string in overridden methods?

Somewhere I saw the suggestions to derive from Sequence and Hashable, but then I couldn't write if 'test' in my_string:?!

Which approach do you recommend?

(*) The reasons are: - write strings that order in an internally defined way - make string (as part of an enumeration), that throw errors when comparing to values outside the enumeration scope

Tom Zych
  • 13,329
  • 9
  • 36
  • 53
Gere
  • 12,075
  • 18
  • 62
  • 94
  • Could you explain what you mean by ABCs? – Ikke Aug 24 '11 at 08:57
  • Hi, I mean http://docs.python.org/py3k/library/abc.html and in particular the ones defined in http://docs.python.org/py3k/library/collections.html#abcs-abstract-base-classes – Gere Aug 24 '11 at 08:59

2 Answers2

4

Here's a silly, but quick, example of Steven's answer. It's implemented in Python 3 (i.e. Unicode strings, super without arguments, and __getitem__ slices):

class MultiStr(str):
    def __new__(cls, string, multiplier=1, **kwds):
        self = super().__new__(cls, string, **kwds)
        self.multiplier = multiplier
        return self

    def __getitem__(self, index):
        item = super().__getitem__(index)
        return item * self.multiplier

>>> s = MultiStr(b'spam', multiplier=3, encoding='ascii')
>>> s[0]
'sss'
>>> s[:2]
'spspsp'
>>> s[:]
'spamspamspam'
Eryk Sun
  • 33,190
  • 5
  • 92
  • 111
  • 1
    Why does the naive approach with `__init__` instead of `__new__` not work`? – Gere Aug 27 '11 at 11:15
  • 2
    @Gerenuk a little late here but: it doesn't work because the `str`-inherited `__new__` method doesn't know about the additional `multiplier` kw argument- when it receives the argument, it doesn't know what to do with it. so you have to handle it in your own. – Rick May 01 '18 at 13:41
1

You can just subclass str, you wouldn't need any mixins because you inherit everything you need from str itself. As for the "data" part: as you're not "simulating" a string (which is what you'd use UserString for), there is no need for a separate "data" part, use the string itself (that is: use self as you would use a string).

(if you mean something else: maybe the question would be clearer by showing your (attempted) code for the overridden methods)

Steven
  • 28,002
  • 5
  • 61
  • 51