[Tutor] question about operator overloading
fomcl at yahoo.com
Mon Mar 5 22:10:26 CET 2012
aha! Good thing I asked. ;-) I've indeed been thinking where this __add__ method should live. The program as it is now has a Generic class, a Reader class and a Writer class. I thought an Append class was appropriate because it uses Reader and Writer (and probably also Generic) methods and the data is from multiple files. It reads a bunch of files (even though the term 'reading' is more a conceptual term here, as none of the data will be held in memory), appends them (__add__), and writes them to one merged file. Doesn't adding __add__ change the responsibility from 'thou shallt read one and only one file' into something less precise?
So if I understand you correctly, the following pseudocode is better?
merged = Reader.readFile(somefile1) + Reader.readFile(somefile2)
# ..which is the same as: Reader.readFile(somefile1).__add__(Reader.readFile(somefile2))
for line in merged:
Maybe this is why my 'top-down code' (what I posted earlier) and my 'bottom-up code' (some code that I wrote earlier) don't add up (pun intended!). In the bottom-up code there was no need for an Append class!
All right, but apart from the sanitation, the medicine, education, wine, public order, irrigation, roads, a
fresh water system, and public health, what have the Romans ever done for us?
> From: Dave Angel <d at davea.name>
>To: Albert-Jan Roskam <fomcl at yahoo.com>
>Cc: Python Mailing List <tutor at python.org>
>Sent: Monday, March 5, 2012 9:36 PM
>Subject: Re: [Tutor] question about operator overloading
>On 03/05/2012 03:16 PM, Albert-Jan Roskam wrote:
>> I am extending a program for a hobby project where potentially huge spss files are read. I would like to add functionality to append files. I thought it would be nice and intuitive to overload + and += for this. The code below is a gross simplification, but I want to get the basics right. Is this the way how operator overloading is usually done?
>> class Append(object):
>> def __init__(self, file1, file2=None):
>> """ file1 and file2 will actually be of a class of my own,
>> which has a readFile method that is a generator that returns
>> one record at a time """
>> self.file1 = file1
>> self.file2 = file2
>> self.merged = 
>> def __add__(self):
>> return self.file1
>> def __iadd__(self):
>> return self.merged
>> def writerows(self):
>> rows = self.file1
>> for row in rows:
>> yield row
>> # overloading '+'
>> file1 = [[1, 2, 3], [4, 5, 6], [6, 6, 6]] file2 = [[1, 2, 3]]
>> app = Append(file1, file2)
>> merged = app.file1 + app.file2 # 'merged' will not actually hold data
>> for line in app.writerows():
>> print line
>> # overloading '+='
>> files = [file1, file2]
>> for i, f in enumerate(files):
>> if i == 0:
>> app = Append(f)
>> app.merged = f
>> app.merged += f
>> print app.merged
>I hate to say it, but it's not even close.
>When you say app.file1 + app.file2, you're not calling either of your special methods you defined in Append. You're just adding the file1 and file2 attributes. Since in your example these are lists, they do the usual thing.
>Similarly, your app.merged += f does NOT call your __iadd__() method.
>Just what kind of an object is an Append object supposed to be? Classes are usually for encapsulating data and behavior, not just to bundle up some functions.
>Normally, you should be defining the __add__() and __iadd__() methods in the class that file1 and file2 are instances of. So if you want to make a dummy example, start by defining a (single) class that holds just one of these. Then create two instances, and try adding and +='ing the two instances.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Tutor