Discuss Why can’t I subclass str (truly) in the Python Programming forum on Dev Shed. Why can’t I subclass str (truly) Python Programming forum discussing coding techniques, tips and tricks, and Zope related information. Python was designed from the ground up to be a completely object-oriented programming language.
Posts: 403
Time spent in forums: 1 Week 5 h 1 m 25 sec
Reputation Power: 65
Why can’t I subclass str (truly)
For a very specific and hidden purpose, I tried to subclass strings. That can be done. What cannot be done, however, is modifying the __init__() function so that the new subclass could take additional parameters different from those of the superclass (which is exactly what I needed).
You can subclass lists this way:
Code:
>>> class Spam(list):
def __init__(self, data=None, eggs=0):
if data is None:
data = []
list.__init__(self, data)
self.eggs = eggs
>>> test = Spam()
>>> test.eggs
0
>>> another_test = Spam(['a', 'b', 'c'], 10)
>>> another_test.eggs
10
Both tests work: I can create a Spam() object, a subclass of list, either with default or explicit values.
With string subclasses, only default value seem to work after the first parameter:
Code:
>>> class MoreSpam(str):
def __init__(self, data='', eggs=0):
str.__init__(self, data)
self.eggs = eggs
>>> test = MoreSpam('')
>>> test.eggs
0
>>> wtf = MoreSpam('', 10)
Traceback (most recent call last):
File "<pyshell#35>", line 1, in <module>
wtf = MoreSpam('', 10)
TypeError: str() argument 2 must be str, not int
It seems that for whatever reason, the __init__() function of the str subclasses is not re-defining the parameter list. Instead, Python looks straight at whatever is in the base class’s parameter list, namely two string parameters: the value of the string object itself and its encoding.
Am I getting this right? Shouldn’t this rightly be called a bug, or am I doing something completely different than I think I’m doing?
__________________
My armada: openSUSE 12.3 (home desktop, laptop, work desktop), Ubuntu 12.04 LTS (mini laptop), Debian GNU/Linux 7.0 (server), Mythbuntu 12.04 LTS (HTPC), Bodhi Linux 2.0 & Windows 7 Ultimate (test desktop), FreeBSD 9.1 (test server)
Posts: 3,357
Time spent in forums: 1 Month 2 Weeks 3 Days 9 h 10 m 17 sec
Reputation Power: 383
looks like a bug to me!
Code:
>>> class c(tuple):
... def __init__(s,a,b):
... tuple.__init__(s,a)
... self.b = b
...
>>> c(tuple(),666)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: tuple() takes at most 1 argument (2 given)
I guess you'll need to write some extra code to work around this. Affects my installations of python 2 and 3.
I'll report it to bugs.python.org reported
__________________
[code]Code tags[/code] are essential for python code!
Posts: 403
Time spent in forums: 1 Week 5 h 1 m 25 sec
Reputation Power: 65
Quote:
Originally Posted by b49P23TIvg
I'm rebuffed at bugs.python.org.
You can't call __init__ on an immutable.
You'll need to use type or str.__new__ or object__new__ but I completely forget how to make this work.
Okay, looks like subclassing immutable objects isn’t so easy I guess I could revert to subclassing “object” and use a silly class variable like self.data to hold the string. Darn. The methods would like much nicer when I could be slicing just “self” instead of “self.data”.
Nice! Although the necessity to “return” anything from __new__() seems strange to me but who cares if it works and doesn’t require much extra code lines.