为 ponyorm 的实体定义构造函数会导致 TypeError

Wom*_*atz 5 python python-3.x ponyorm

我只是想尝试一下用于小型个人 Web 应用程序的 pony orm 映射器。除了为实体定义自定义构造函数之外,一切正常。

在下面的代码中,我创建了一个带有字符串字段的简单实体name,并定义了一个构造函数,该构造函数除了将参数重定向到父构造函数之外什么也不做(在我的真实应用程序中,我在将它们传递给父构造函数之前更改了一些参数)。之后我创建一个User并打印它的名称。

from pony.orm import Database, Required, db_session, commit


db = Database("sqlite", ":memory:", create_db=True)


class User(db.Entity):
    def __init__(self, *args, **kwargs):
        super(User, self).__init__(*args, **kwargs)

    name = Required(str)


db.generate_mapping(create_tables=True)

with db_session:
    u = User(name="Admin")
    commit()
    print(u, u.name)
Run Code Online (Sandbox Code Playgroud)

错误消息TypeError: object.__init__() takes no parameters与调用位于同一行super()。看起来关键字参数被发送到object而不是db.Entity. 当我删除构造函数时,一切正常

那么为什么它不起作用呢。难道像我的例子中的构造函数不应该总是工作(当然什么也不做)吗?ponyorm 中是否有某些东西阻止它工作,或者我在这里遗漏了一些东西?

为了完整起见,我的实体定义实际上是这样的

class User(db.Entity):
    def __init__(self, *args, **kwargs):
        if "password" not in kwargs:
            raise ValueError("password is required")
        kwargs["password"] = werkzeug.security.generate_password_hash(kwargs["password"])
        super().__init__(*args, **kwargs)

    name = Required(str)
    password = Required(str)
Run Code Online (Sandbox Code Playgroud)

它产生相同的结果。

另外,在官方文档中,它表示至少允许在实体中创建方法。http://doc.ponyorm.com/entities.html#adding-custom-methods-to-entities。但它没有提及任何有关构造函数的内容。

Ale*_*sky 4

在那之前,班级根本Entity没有这个方法。__init__由于历史原因,实体实例的初始化发生在该__new__方法中。因此,当您调用时,super(User, self).__init__您实际上调用了该object.__init__方法。在 Python 2 中,该object.__init__方法默默地接受任何参数,而在 Python 3 中,当您向该方法传递任何参数时,该方法会引发错误(您遇到的错误)。

在查看您的问题后,我们更改了实体实例的初始化逻辑,现在我们__init__以传统方式使用方法。如果您从 GitHub 获取最新版本的 PonyORM,您的代码应该可以正常工作。此更改将成为下一版本 PonyORM 0.6.2 的一部分。

感谢您指出这一点!