[Tutor] question about operator overloading

Peter Otten __peter__ at web.de
Tue Mar 6 09:35:08 CET 2012


Dave Angel wrote:

> On 03/05/2012 06:20 PM, Alan Gauld wrote:
>> On 05/03/12 21:25, Dave Angel wrote:
>>
>>> It's not clear what __add__() should mean for physical files.
>>
>> My guess would be similar to the cat operator in Unix:
>>
>> $ cat file1, file2 > file3
>>
>> is equivalent to
>>
>> file3 = file1 + file2
>>
>> But of course, thats just my interpretation of file addition...
>>
> 
> So somehow assigning the object to file3 will write the data to a file
> by the name "file3" ?  I know about __add__(), but didn't know we had
> __assign__()

That is indeed one problem that makes an approach based on operator 
overloading clumsy here. You can either invent a name for file3
or defer writing the file:

file3 = file1 + file2
file3.save_as(filename)

Below is an implementation with a made-up destination file name:

$ cat roskam.py
import os

def remove(filename):
    try:
        os.remove(filename)
    except OSError:
        pass

class File(object):
    def __init__(self, filename):
        self.filename = filename
    def __iadd__(self, other):
        with  self.open("a") as dest, other.open() as source:
            dest.writelines(source)
        return self
    def __add__(self, other):
        result = File("+".join([self.filename, other.filename]))
        remove(result.filename)
        result += self
        result += other
        return result
    def open(self, *mode):
        return open(self.filename, *mode)
    def __str__(self):
        return self.filename + ":\n" + "".join("    " + line for line in 
self.open())

if __name__ == "__main__":
    remove("file3")
    remove("file4")

    with open("file1", "w") as f:
        f.write("""\
alpha
beta
gamma
""")
    with open("file2", "w") as f:
        f.write("""\
DELTA
EPSILON
""")

    file1, file2, file3 = map(File, ["file1", "file2", "file3"])
    file3 += File("file1")
    file3 += File("file2")
    
    file4 = file2 + file1 + file2

    for f in file1, file2, file3, file4:
        print f

$ python roskam.py 
file1:
    alpha
    beta
    gamma

file2:
    DELTA
    EPSILON

file3:
    alpha
    beta
    gamma
    DELTA
    EPSILON

file2+file1+file2:
    DELTA
    EPSILON
    alpha
    beta
    gamma
    DELTA
    EPSILON

The code is meant to illustrate the implementation of __add__() and 
__iadd__(), I don't recommend that you actually use it. You can easily 
achieve the same with a for loop that is concise and easy to understand:

with open(destname, "wb") as dest:
    for sourcename in sourcenames:
        with open(sourcename, "rb") as source:
            shutil.copyfileobj(source, dest)




More information about the Tutor mailing list