python - 是否有基于类属性创建 __init__ 函数的快捷方式?

标签 python class oop sqlalchemy

我正在使用 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/

相关文章:

c++ - 如何从主类之外的嵌套类编写实际代码

javascript - 使用不同名称别名或以其他方式合并两个相同的对象原型(prototype)

php - 抽象类方法声明

python - 导入错误 : cannot import name 'Feature' from 'setuptools

python - Sqlite3 无法正确查询 UTF-8 字符串?

python - 属性错误: 'OLSResults' object has no attribute 'norm_resid'

c++ - 继承错误: expected class-name before '{' token

c# - 如何使用抽象基类继承内部类?

python - 使用 (x,y) 坐标到达特定的 "village"(Python 3)

python - actix Actor怎么会有PyO3 Python?