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" _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor