我正在使用 sqlalchemy 的 ORM,并且我有一堆带有类属性的声明性类。例如:
class Example(Declarative):
id = Column(Integer, primary_key=True)
datum = Column(String(65))
当然,我的类(class)比这个例子长得多,我大约有两打。我希望能够在实例化时填充它们的字段,因此每个类都有 __init__ 函数会很好。
简单的方法如下:
def __init__(self, id, datum):
self.id = id
self.datum = datumi
这变得非常乏味。有某种捷径吗?也许我可以利用Example.__dict__
?这些是新式的类。
最佳答案
您根本不需要创建 __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__
属性中给出存储的字段顺序。
关于python - 是否有基于类属性创建 __init__ 函数的快捷方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18151261/