I have a conceptual Python design dilemma.
Say I have a City
class, which represents a city in the database. The City
object can be initialized in two ways:
name
, country
, population
, ...), which will generate a new city in the database, and retrieve its ID.This means that the City object will always have an ID - either the initialized ID or a newly-created ID derived from the database.
The classic Java approach would overload the constructor - One constructor would get a single int
parameter, and the other would get numerous strongly-typed parameters.
get_city_id
, and derive CityFromID
and
CityFromNewData
from it, but that's a lot of effort to work around this language lacuna.Using **kargs
seems very inelegant, because the signature of the constructor does not clearly state the required input parameters, and docstrings just ain't enough:
class City(object):
def __init__(self, city_id=None, *args, **kargs):
try:
if city_id==None:
self.city_id=city_id
else:
self.city_name=kargs['name']
except:
error="A city object must be instanciated with a city id or with"+\
" full city details."
raise NameError(error)
Is there a Pythonic, elegant solution to constructor overloading?
Adam
How about:
class City(object):
def __init__(self, name, description, country, populations):
self.city_name = name
# etc.
@classmethod
def from_id(cls, city_id):
# initialise from DB
Then you can do normal object creation:
>>> c = City('Hollowberg', '', 'Densin', 3)
>>> c.id
1233L
>>> c2 = City.from_id(1233)
~~~~~~
Also you might want to check out SQLAlchemy (and Elixir) for nicer ways to do these things
There is a design pattern called Data Access Object that is usually used in your case. According to it you should separate fetching and creation of data objects in two classes City and CityDAO:
class City:
def __init__(self, name, country):
self.name = name
self.country = country
class CityDAO:
def fetch(self, id):
return query(...)
def insert(self, city):
query(...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With