我正在使用sqlalchemy的ORM,我有一堆具有类属性的Declarative
类。例如:
class Example(Declarative):
id = Column(Integer, primary_key=True)
datum = Column(String(65))
当然,我的课程比这个例子长得多,我有大约二十几个。我希望能够在实例化时填充它们的字段,因此为每个类提供__init__
函数会很好。
这种天真的做法如下:
def __init__(self, id, datum):
self.id = id
self.datum = datumi
这非常繁琐。有某种捷径吗?也许我可以利用Example.__dict__
?这些是新式的课程。
答案 0 :(得分:3)
您根本不需要创建__init__
方法; SQLAlchemy为您提供了一个开箱即用的功能。
即使您必须构建一个,也可以接受任意关键字参数。这正是SQLAlchemy版本的作用:
def _declarative_constructor(self, **kwargs):
"""A simple constructor that allows initialization from kwargs.
Sets attributes on the constructed instance using the names and
values in ``kwargs``.
Only keys that are present as
attributes of the instance's class are allowed. These could be,
for example, any mapped columns or relationships.
"""
cls_ = type(self)
for k in kwargs:
if not hasattr(cls_, k):
raise TypeError(
"%r is an invalid keyword argument for %s" %
(k, cls_.__name__))
setattr(self, k, kwargs[k])
翻译成散文,此方法测试您传入的每个关键字是否是该类的属性,然后才使用setattr()
在实例上设置值。
请注意,这使用关键字参数;您无法使用位置参数执行此操作,因为您的类属性存储在字典中,因此没有设置顺序。如果要使用位置参数,则需要手动创建__init__
方法,或者在类上为(继承的)__init__
定义订单以使用:
class Example(Declarative):
id = Column(Integer, primary_key=True)
datum = Column(String(65))
__order__ = ('id', 'datum')
def __init__(self, *args, **kwargs):
cls_ = type(self)
kwargs.update(zip(cls_.__order__, args))
for k in kwargs:
if not hasattr(cls_, k):
raise TypeError(
"%r is an invalid keyword argument for %s" %
(k, cls_.__name__))
setattr(self, k, kwargs[k])
此处,在类的新kwargs
属性中给定存储的字段顺序时,任何位置参数都会合并到__order__
。
答案 1 :(得分:1)
您可以定义一个将字典作为输入的类,并执行以下操作:
for (k, v) in inital_dict.iteritems():
setattr(self, k, v)
如果从该类继承,则所有新类都具有相同的方法,您可以使用super
调用它。