为 ponyorm 的实体定义构造函数导致 TypeError
Defining a constructor for ponyorm's Entities results in TypeError
我只是想为一个小型个人 Web 应用程序试用 pony orm 映射器。
除了为实体定义自定义构造函数外,一切正常。
在下面的代码中,我创建了一个带有字符串字段的简单实体 name
并定义了一个构造函数,它除了将参数重定向到父构造函数外什么都不做(在我的真实应用程序中,我更改了一些参数 bevor将它们传递给父构造函数)。之后我创建一个 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)
错误消息 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)
它产生相同的结果。
同样在官方文档中它说至少允许在实体中创建方法。 http://doc.ponyorm.com/entities.html#adding-custom-methods-to-entities。
但它没有说明构造函数。
直到那一刻 Entity
class 根本没有 __init__
方法。由于历史原因,实体实例的初始化发生在 __new__
方法中。因此,当您调用 super(User, self).__init__
时,您实际上调用了 object.__init__
方法。在 Python 2 中,object.__init__
方法默默地接受任何参数,而在 Python 3 中,当您向它传递任何参数时,该方法会引发错误(您遇到的错误)。
在查看您的问题后,我们更改了实体实例的初始化逻辑,现在我们以传统方式使用 __init__
方法。如果您使用 GitHub 的最新版本的 PonyORM,您的代码应该可以正常工作。此更改将成为下一个版本 PonyORM 0.6.2 的一部分。
感谢您指出这一点!
我只是想为一个小型个人 Web 应用程序试用 pony orm 映射器。 除了为实体定义自定义构造函数外,一切正常。
在下面的代码中,我创建了一个带有字符串字段的简单实体 name
并定义了一个构造函数,它除了将参数重定向到父构造函数外什么都不做(在我的真实应用程序中,我更改了一些参数 bevor将它们传递给父构造函数)。之后我创建一个 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)
错误消息 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)
它产生相同的结果。
同样在官方文档中它说至少允许在实体中创建方法。 http://doc.ponyorm.com/entities.html#adding-custom-methods-to-entities。 但它没有说明构造函数。
直到那一刻 Entity
class 根本没有 __init__
方法。由于历史原因,实体实例的初始化发生在 __new__
方法中。因此,当您调用 super(User, self).__init__
时,您实际上调用了 object.__init__
方法。在 Python 2 中,object.__init__
方法默默地接受任何参数,而在 Python 3 中,当您向它传递任何参数时,该方法会引发错误(您遇到的错误)。
在查看您的问题后,我们更改了实体实例的初始化逻辑,现在我们以传统方式使用 __init__
方法。如果您使用 GitHub 的最新版本的 PonyORM,您的代码应该可以正常工作。此更改将成为下一个版本 PonyORM 0.6.2 的一部分。
感谢您指出这一点!