[Tutor] feedback on simple python code
Peter Otten
__peter__ at web.de
Tue Feb 28 03:32:54 EST 2017
Ryan Smith wrote:
> Hi all,
>
> New python student here. I have been using O¹reilly¹s "Python Beyond the
> Basics: Object Oriented Programming video series". In one of the
> assignments we are to write a simple inheritance hierarchy of three
> classes that write to text files. I have actually written the code for the
> assignment and it runs as well as meets the requirements of the
> assignment. I am posting to get feedback on how I can improve this and
> making it more pythonic and concise.
>
> Please keep in mind that I am simply ³simulating" writing to a log file
> and a tabbed delimited file, so I¹m not necessarily looking for which
> modules I could have to create actual log files or writing to actual csv
> files. The output of the code should be two text files with text written
> to them that have been passed to the instance of each respective object.
>
> #!/usr/bin/env python
>
> import abc
> import datetime
>
> class WriteFile(object):
> __metaclass__ = abc.ABCMeta
>
>
> @abc.abstractmethod
> def write(self,text):
You might run a tool like https://pypi.python.org/pypi/pycodestyle over your
code to ensure it follows common standards.
> """Write to file"""
> return
>
>
> class LogFile(WriteFile):
> def __init__(self,fh):
> self.fh = fh
>
>
> def write(self, text):
> date = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
> entry = "{0} {1}{2}".format(date, text, '\n')
> with open(self.fh, 'a') as f:
> f.write(entry)
>
> class DelimWrite(WriteFile):
> def __init__(self, fh, delim):
> self.fh = fh
> self.delim = delim
>
>
> def write(self, text):
> with open(self.fh, 'a') as f:
> entry = ""
> for item in text:
> if self.delim in item:
> entry += ' "{0}"{1} '.format(item,self.delim)
What will happen if text contains double quotes?
> else:
> entry += item+self.delim
Have a look at the str.join() method. Example:
>>> ",".join(["foo", "bar", "baz"])
'foo,bar,baz'
> f.write(entry.strip(self.delim) + '\n')
I will mention another "principle", DRY (don't repeat yourself), i. e. do
not write the same code twice.
When I look at your code I see that both DelimWrite and LogFile open a file.
If you want modify your code to accept file objects like sys.stdout you have
to make changes in both subclasses. To avoid that you might put the file-
writing part into a separate method:
class WriteFile(object):
def __init__(self, file):
self.file = file
def write_record(self, record):
with open(self.file, "a") as f:
f.write(self.format_record(record))
def format_record(self, record):
return record
class LogFile(WriteFile):
def format_record(self, record):
date = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
return "{0} {1}\n".format(date, record)
class DelimWrite(WriteFile):
quote = '"'
def __init__(self, file, delimiter):
super(DelimWrite, self).__init__(file)
self.delimiter = delimiter
def escaped(self, value):
value = str(value)
if self.delimiter in value:
quote = self.quote
value = '"{}"'.format(value.replace(quote, quote + quote))
return value
def format_record(self, record):
escaped_rows = (self.escaped(value) for value in record)
return self.delimiter.join(escaped_rows) + "\n"
More information about the Tutor
mailing list