473,799 Members | 3,080 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Code design for a sub-class of built-ins

I'm having problems with sub-classes of built-in types.

Here is a contrived example of my subclass. It isn't supposed
to be practical, useful code, but it illustrates my problem.

class MyStr(str):
"""Just like ordinary strings, except it exhibits special behaviour
for one particular value.
"""
magic = "surprise"
def __init__(self, value):
str.__init__(se lf, value)
def __len__(self):
if self == self.magic:
print "Nobody expects the Spanish Inquisition!"
return str.__len__(sel f)
def upper(self):
if self == self.magic:
print "Nobody expects the Spanish Inquisition!"
return str.upper(self)
# and so on for every last string method...
The obvious problem is, I have to create a custom method for every string
method -- and if strings gain any new methods in some future version of
Python, my subclass won't exhibit the correct behaviour.

Here's a slightly different example:

class MyInt(int):
"""Like an int but with special behaviour."""
def __init__(self, value, extra):
int.__init__(se lf, value=None)
self.extra = extra
def __add__(self, other):
if self.extra is None:
return int.__add__(sel f, other)
else:
return int.__add__(sel f, other) + self.extra
# and again with all the other methods

This one doesn't even work!
>>i = MyInt(5, 6)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: int() can't convert non-string with explicit base

Looks like my __init__ isn't even being called here. Why not, and how do I
fix this?

Is there a way to subclass built-in types without needing to write the
same bit of code for each and every method?

Am I approaching this the wrong way? Is there a better design I could be
using?

Thanks,

--
Steven.

Jul 4 '06 #1
7 1375
Steven D'Aprano wrote:
I'm having problems with sub-classes of built-in types.

Here is a contrived example of my subclass. It isn't supposed
to be practical, useful code, but it illustrates my problem.

class MyStr(str):
"""Just like ordinary strings, except it exhibits special behaviour
for one particular value.
"""
magic = "surprise"
def __init__(self, value):
str.__init__(se lf, value)
You don't need to override __init__ here.

def __len__(self):
if self == self.magic:
print "Nobody expects the Spanish Inquisition!"
return str.__len__(sel f)
def upper(self):
if self == self.magic:
print "Nobody expects the Spanish Inquisition!"
return str.upper(self)
# and so on for every last string method...
My my my....
>
The obvious problem is, I have to create a custom method for every string
method --
which makes subclassing almost useless - except to pass isinstance() tests.
and if strings gain any new methods in some future version of
Python, my subclass won't exhibit the correct behaviour.
You could replace subclassing by composition/delegation using the
__getattr__ hook, but this would break tests on type/class :(

Or you could keep subclassing and use the __getattribute_ _ hook, but
this is more tricky and IIRC may have negative impact on lookup perfs.

Or you could use a metaclass to decorate (appropriate) str methods with
a decorator doing the additional stuff.

choose your poison !-)
Here's a slightly different example:

class MyInt(int):
"""Like an int but with special behaviour."""
def __init__(self, value, extra):
int.__init__(se lf, value=None)
self.extra = extra
Won't work. You need to override the __new__ staticmethod. Look for
appropriate doc here:
http://www.python.org/download/relea...intro/#__new__
(FWIW, read the whole page)

(snip)
Looks like my __init__ isn't even being called here. Why not, and how do I
fix this?
cf above
Is there a way to subclass built-in types without needing to write the
same bit of code for each and every method?
cf above
Am I approaching this the wrong way? Is there a better design I could be
using?
probably !-)

HTH
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom. gro'.split('@')])"
Jul 4 '06 #2
Steven D'Aprano <st***@REMOVETH IScyber.com.auw rote:
...
The obvious problem is, I have to create a custom method for every string
method -- and if strings gain any new methods in some future version of
Python, my subclass won't exhibit the correct behaviour.
As others already suggested, automating such decoration is pretty easy;
you can do it with either a custom metaclass or a simple post-processing
of your class in a loop. Untested details below, but the general idea
would be something like:

class SDAstr(str):
magic = 'whatever'

def _SDAdecorate(me thodname, strmethod):
def decorated(self, *a, **k):
if self == self.magic: print "whatever!"
return strmethod(self, *a, **k)
setattr(SDAstr, methodname, decorated)

for methodname, strmethod in \
inspect.getmemb ers(str, inspect.ismetho ddescriptor):
_SDAdecorate(me thodname, strmethod)

and variants thereof (to provide more accurate metainformation with the
decorated methods -- name, docstring, signature, whatever; and/or to
encapsulate things in a custom metaclass; whatever).

class MyInt(int):
"""Like an int but with special behaviour."""
def __init__(self, value, extra):
...
Looks like my __init__ isn't even being called here. Why not, and how do I
fix this?
Override __new__, which is what invariably gets called (before __init__,
which only gets called if __new__ returns an instance of the class that
you're instantiating).
Alex
Jul 4 '06 #3
On Tue, 04 Jul 2006 19:26:36 +0200, Bruno Desthuilliers wrote:
Steven D'Aprano wrote:
>I'm having problems with sub-classes of built-in types.

Here is a contrived example of my subclass. It isn't supposed
to be practical, useful code, but it illustrates my problem.

class MyStr(str):
"""Just like ordinary strings, except it exhibits special behaviour
for one particular value.
"""
magic = "surprise"
> def __init__(self, value):
str.__init__(se lf, value)

You don't need to override __init__ here.
Perhaps not, but in a more realistic example I might need to.

> def __len__(self):
if self == self.magic:
print "Nobody expects the Spanish Inquisition!"
return str.__len__(sel f)
def upper(self):
if self == self.magic:
print "Nobody expects the Spanish Inquisition!"
return str.upper(self)
# and so on for every last string method...

My my my....
Exactly. Don't think I don't know this is a horrible strategy -- that's
why I'm asking for ideas for a better way to do it *wink*

>The obvious problem is, I have to create a custom method for every
string method --

which makes subclassing almost useless - except to pass isinstance()
tests.
Yep.

>and if strings gain any new methods in some future version of Python,
my subclass won't exhibit the correct behaviour.

You could replace subclassing by composition/delegation using the
__getattr__ hook, but this would break tests on type/class :(

Or you could keep subclassing and use the __getattribute_ _ hook, but
this is more tricky and IIRC may have negative impact on lookup perfs.

Or you could use a metaclass to decorate (appropriate) str methods with
a decorator doing the additional stuff.

choose your poison !-)
Interesting... That will give me something to experiment with.
Thanks,
--
Steven.

Jul 5 '06 #4
On Tue, 04 Jul 2006 18:25:14 +0000, Dennis Lee Bieber wrote:
I suspect what you really want (I'm not going to open an interpreter
to test) is:

def __init__(self, value, extra=None):
int.__init__(se lf, value)
Yes, that's exactly what I meant -- it was a copy-and-paste and I didn't
clean it up correctly.

Thanks,
--
Steven.

Jul 5 '06 #5
Steven D'Aprano wrote:
On Tue, 04 Jul 2006 19:26:36 +0200, Bruno Desthuilliers wrote:

>>Steven D'Aprano wrote:
>>>I'm having problems with sub-classes of built-in types.

Here is a contrived example of my subclass. It isn't supposed
to be practical, useful code, but it illustrates my problem.

class MyStr(str):
"""Just like ordinary strings, except it exhibits special behaviour
for one particular value.
"""
magic = "surprise"
>> def __init__(self, value):
str.__init__(se lf, value)

You don't need to override __init__ here.


Perhaps not, but in a more realistic example I might need to.
Perhaps, but I can only comment on the example you gave !-)
Also, *you* are aware of this, but please keep in mind that cl.py is
read by a lot of newbies.

(snip)
>>You could replace subclassing by composition/delegation using the
__getattr__ hook, but this would break tests on type/class :(

Or you could keep subclassing and use the __getattribute_ _ hook, but
this is more tricky and IIRC may have negative impact on lookup perfs.

Or you could use a metaclass to decorate (appropriate) str methods with
a decorator doing the additional stuff.

choose your poison !-)


Interesting... That will give me something to experiment with.
AFAICT, the last solution is probably the better of the three (well, at
least it's the better I can think of actually).

For the record, care to give more informations about your real use case?

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom. gro'.split('@')])"
Jul 5 '06 #6
On Tue, 04 Jul 2006 16:41:38 -0700, Alex Martelli wrote:
As others already suggested, automating such decoration is pretty easy;
you can do it with either a custom metaclass or a simple post-processing
of your class in a loop. Untested details below, but the general idea
would be something like:
That's great, thanks. You've given me an angle of attack to take and see
where it leads.
--
Steven.

Jul 5 '06 #7
On Wed, 05 Jul 2006 11:41:47 +0200, Bruno Desthuilliers wrote:
Steven D'Aprano wrote:
>On Tue, 04 Jul 2006 19:26:36 +0200, Bruno Desthuilliers wrote:

>>>Steven D'Aprano wrote:

I'm having problems with sub-classes of built-in types.

Here is a contrived example of my subclass. It isn't supposed
to be practical, useful code, but it illustrates my problem.
[snip]
For the record, care to give more informations about your real use case?
Equal parts a learning exercise and a simple example of a genetic
algorithm.

I felt that the natural way to approach this would be for an object to
mutate itself, rather than have an external function that operated on a
string and returned a new string. The obvious approach was to subclass str
and give it methods to modify itself in place, but of course strings are
immutable.

This got me wondering how hard it would be to create a mutable string
class, whether I should look at subclassing list (to get the mutability)
and then add string-like methods to it, or try something completely
different.

A little bit of experimentation soon had me realising that I didn't
understand Python's new-style class model well enough to do these things
properly, hence the learning exercise.
Thanks for everybody's help on this.

--
Steven.

Jul 5 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
2480
by: David Deacon | last post by:
Hi i was given the following advise,below my OriginalQuestion I am a little new to ADOX can you direct me to the following Do i place the code behind a button on a form? Or do i place it in the On Open event and have a the default 10% and give the user the option to change it to 0% I have referenced th appropriate library and the default value of the field to change is 0.1
2
1780
by: Douglas Buchanan | last post by:
I set the OnExit property of the "Cost" field in subform "subJobDetail" to save the record (see below). Then I call a global sub to copy the )] calculated field to a field in the subform "subJob". The record in "subJob" displays the "writing" (pencil) icon for the record but does not update visually until I enter and exit a second field "Markup" that is identically coded. How do I write code to save the record in the subform "subJob" ...
7
1324
by: Mathew Hill | last post by:
I am a beginner to the more technical aspects of Microsoft Access (2000) and was wondering if any one can help. I have 3 buttons on a form which add, delete and search for a record. However, when I click on the respective buttons absolutely nothing happens! I was wondering if anyone could help? The code I have is below... ADDING A RECORD Private Sub cmdaddstudent_Click() On Error GoTo Err_cmdaddstudent_Click
18
18433
by: Dixie | last post by:
Can I set the Format property in a date/time field in code? Can I set the Input Mask in a date/time field in code? Can I set the Format of a Yes/No field to Checkbox in code? I am working on a remote update of tables and fields and can't find enough information on these things. Also, how do you index a field in code?
4
2199
by: Jozef | last post by:
Hello, I'm trying to check for and add a field to a table to a back end database through code. The problem I've been faced with is changing permissions, because I have to use administer permissions to change the design, then remove the delete permissions when the design has been changed. I have to do it in code because there are several sites that need an automated update (as opposed to manually adding the field). The platform is...
46
2499
by: Profetas | last post by:
Hi, I know that this is off topic. but I didn't know where to post. Do you comment your source code while coding or after coding. for example: you write a procedure and after it is working, you'll comment it.
12
4554
by: GaryDean | last post by:
In the original post I failed so indicate that I am using framework 1.1....... I need to be able to change the background color of a page from code. I found an answer to this question in another forum from Peter Huang that said that an id="bg" as follows... <body MS_POSITIONING="GridLayout" runat="server" id="bg"> then we could do the following in our codebehind file....
8
1466
by: darnnews | last post by:
I have a form. When a person selects a publication from a listbox, this snippet of code is supposed to look up authors that correspond to that publication and populate the Author List Box, but it doesn't work. I have been hacking away at it for a while to no avail. Can anyone spot the bug(s)? The RowSource property of Authors gets set to the following by this code, if that helps you help me:
2
1079
by: Water Cooler v2 | last post by:
I want my application to do three tasks simultaneously. Each of the three tasks must be performed at a periodic interval of time. Each of the three tasks is somewhat complicated and is thus composed of a number of sub-tasks that are to be performed in a linear sequence. The three tasks are independent of each other. They do not share any data, nor is the execution of one going to affect the other. To ampify, assume I have three main...
2
3491
by: =?Utf-8?B?RnJlZW1hbg==?= | last post by:
Hi, I'm new to vb.net. How to prevent vb.net to automatic execute code in design time? When I open a form design view in VS2005, vs pop up an error message: "Could not load file or assembly "xxx" or one of its dependencies....". But there's no build error, and can run normally.The renferenced assembly(not strongly named) do exist, but not in GAC. I wonder there's any way to disable the error check when I open the form?
0
9687
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10484
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10251
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9072
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6805
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5463
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5585
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4141
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3759
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.