[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