Определение конструктора для объектов Ponyorm приводит к TypeError
Я просто хотел опробовать Pony Orm Mapper для небольшого личного веб-приложения. Все работает отлично, за исключением определения собственного конструктора для объекта.
В следующем коде я создал простую сущность со строковым полем 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)
Сообщение об ошибке TypeError: object.__init__() takes no parameters
в той же строке, что и super()
вызов. Похоже, что ключевые аргументы отправляются object
вместо db.Entity
, Когда я удаляю конструктор все работает
Так почему же это не работает? Разве конструктор, как в моем примере, не должен всегда работать (и, конечно, ничего не делать)? Есть ли в поныме что-то, что мешает ему работать, или я что-то здесь упускаю?
Для полноты картины мое определение сущности на самом деле выглядит так
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. Но это ничего не говорит о конструкторах.
1 ответ
До этого момента Entity
класс не имел __init__
метод вообще. По историческим причинам инициализация экземпляра объекта произошла в __new__
метод. Из-за этого, когда вы звоните super(User, self).__init__
ты на самом деле называешь object.__init__
метод. В то время как в Python 2 object.__init__
Метод молча принимает любые аргументы, в Python 3 этот метод вызывает ошибку (ту, которая у вас есть), когда вы передаете ему любой аргумент.
Посмотрев на ваш вопрос, мы изменили логику инициализации экземпляров сущностей и теперь используем __init__
метод традиционным способом. Если вы берете последнюю версию PonyORM из GitHub, ваш код должен работать нормально. Это изменение будет частью следующего выпуска PonyORM 0.6.2.
Спасибо за указание на это!