Определение конструктора для объектов 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.

Спасибо за указание на это!

Другие вопросы по тегам