On 13Jun2018 15:23, Fabien LUCE <fabienl...@gmail.com> wrote:
Here is a small picture of my project.
I'd like to fetch several datas from a website representing races results.
Each line of the result contains rank, runner's name and other attributes
of the runner (like club etc...).
For now I have created 2 classes (Race and Runner).
Methods of Race allow me to fetch datas on the www thanks to beautifulsoup
module.I instanciate a race at the beginning of the scan and for each line
I instanciate a Runner.
I want to store all those information in a database (for both Race and
Runner), but here is the point, I have the feeling, on a programming
elegance point of view, that I have to separate methods that fetch from
method that store and also have a kind of superior object that controls
those 2 features.
Moreover fetching will interact with storage: if race is already in
database, no need to fetch again.
How should I "design" this? Should I have only (despite my first
impression) one class and all the methods in it? Should I create a parent
class along with 2 childrens that manage the two kind of methods?
Is there a design pattern for this?

My inclination would be to start by providing a class which "wraps" your Race database table, and presents it as a mapping.

Something along the lines of:

 class RaceTable:
   def __init__(self, database_connection, table_name):
     self.conn = database_connection
     self.table_name = table_name
   def __contains__(self, race_id):
     ... do SQL to see if the race_id is already present, return True or False
   def __getitem__(self, race_id):
     ... do SQL to fetch a Race row from the table and return it ...
   def __setitem__(self, race_id, race_info):
     ... do SQL to store race_info in the table ...

The special __foo__ methods (called "dunder" methods in the Puython world because of the "double underscore") are what make the class look like a Python "dict" from outside: when you perform a mapping method like "value in x" or "x[key] = value", Python calls x.__contains__ or x.__setitem__ for you.

Look up "Emulating Container Types" here:

 https://docs.python.org/3/reference/datamodel.html#emulating-container-types

That will show you how to write a class like the above example to implement a "maping" interface. You don't need to implement everything, just what you need. The example above only implements 3 methods.

Then your outer code can look a bit like:

 race_store = RaceTable(database_connection, 'race_table_name_here')
 ...
 if race_id in race_store:
   ... mention that this race_id is already stored ...
 else:
   race_store[race_id] = race_info

So the objective here is a simple class that makes it easy to talk about where your information is stored in nice Pythonic terms, and which hides the details of database access - that lets you talk about the data in a sensbile and clear way outside the storage class, and also leaves scrope for changing the storage mechanism later without changing the main code (eg from a conventional SQL database to some other service).

Cheers,
Cameron Simpson <c...@cskk.id.au>
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to