我有一个概念性的Python设计困境。
假设我有一个City
类,它代表数据库中的一个城市。 City
对象可以通过两种方式初始化:
name
,country
,population
,...),它们将在数据库中生成新城市并检索其ID。这意味着City对象将始终具有ID - 初始化ID或从数据库派生的新创建ID。
经典的Java方法overload the constructor - 一个构造函数将获得一个int
参数,另一个将获得许多强类型参数。
get_city_id
创建基类,并派生CityFromID
和。{
CityFromNewData
来自它,但要努力解决这种语言缺陷。使用**kargs
似乎非常不优雅,因为构造函数的签名没有明确说明所需的输入参数,而文档字符串是不够的:
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)
构造函数重载是否有Pythonic,优雅的解决方案?
亚当
答案 0 :(得分:7)
怎么样:
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
然后你可以做普通的对象创建:
>>> c = City('Hollowberg', '', 'Densin', 3)
>>> c.id
1233L
>>> c2 = City.from_id(1233)
~~~~~~
另外,您可能需要查看SQLAlchemy(以及Elixir)以获得更好的方法来执行这些操作
答案 1 :(得分:4)
有一种名为Data Access Object的设计模式通常用于您的案例中。根据它,您应该在两个类City和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(...)
答案 2 :(得分:2)
我认为类(工厂)方法是最好的方法,因为方法名称已经明确说明了所做的事情。两个独立的功能也可以:
def load_existing_city(id):
...
def create_new_city(name, population, ...):
...