[Tutor] associating two objects without ORM and processing a text file
Alan Gauld
alan.gauld at btinternet.com
Tue Feb 12 00:16:40 CET 2013
On 11/02/13 22:49, neubyr wrote:
> is right approach to implement 'list_by_author' function as a class
> method is typically used as an alternative constructor.
Not at all that is only one use case for class methods.
A class method is *any* method that operates on the whole class of
objects - i.e. all instances(potentially including those still to be
created)
Now I agree that in some lanmguages they tend to be limited to factory
metjods(eg Objective C implicitly goes that way) but in others like
Smalltalk search methods and persistence etc are often found as class
methods. In Python, because of it's hybrid nature, these are often
"demoted" to global scope functions.
> Here I am
> returning list of objects and not just an object.
Which is to say a subset of the class Book.
Therefore quite reasonably a class method.
> @classmethod
> def list_by_author(self,author):
> """ Return list of books of an author """
> bookfile = config.bookfile
> books = [] # empty list - used as list of Books
> # TODO: improve regex
> regex = re.compile(author)
> with open (bookfile,'r') as f:
> for line in f:
> if regex.findall(line):
> # error prone - if name contains comma
> l = line.split(',')
> # create book object and append it to a list
> book = self(*l)
> books.append(book)
> return books # return list of books
I'd probably, for a small dataset, load a list of books into the class
at startup and save it at termination. Which makes the search code
easier and potentially can be data driven so you pass the filter
attribute as a parameter. You can then use getattr() to find the value:
def findBooks(cls, param, value):
return [book for book in books if getattr(book, param) == value]
You could make it more flexible still by defining the filter as a
function and passing a lambda:
def findBooks(cls, filterExp):
return [book for book in books if filterExp(book)]
Usage example:
DickensBooks = Book.findBook(lambda b: 'Dickens' in b.author)
Of course if you have a huge dataset then that won't work - which brings
us back to a database :-)
HTH
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
More information about the Tutor
mailing list