Hello, thanks for this nice answer I didn't see at first (I have parallely asked again in the list, sorry about the inconvenience). I will read deeply your proposal I will come bakc with my quesitons if any ;)
Thanks! June 14 2018 12:37 AM, "Cameron Simpson" <c...@cskk.id.au> wrote: > 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 -- https://mail.python.org/mailman/listinfo/python-list