Есть ли причина, по которой в руководстве по SQLAlchemy ORM угловые скобки заключаются в значения __repr__? - PullRequest
4 голосов
/ 22 ноября 2011

В учебнике по SQLAlchemy ORM используется этот класс:

>>> from sqlalchemy import Column, Integer, String
>>> class User(Base):
...     __tablename__ = 'users'
...
...     id = Column(Integer, primary_key=True)
...     name = Column(String)
...     fullname = Column(String)
...     password = Column(String)
...
...     def __init__(self, name, fullname, password):
...         self.name = name
...         self.fullname = fullname
...         self.password = password
...
...     def __repr__(self):
...        return "<User('%s','%s', '%s')>" % (self.name, self.fullname, self.password)

Зачем вам идти на то, чтобы иметь строку, которая будет хорошо работать при eval() 'd, только чтобы сломать эту функциональность, но окружающиеэто с угловыми скобками?

Я понимаю, что идиома eval(repr(foo)) далека от единственной цели __repr__, но все же кажется странным, что она здесь намеренно отключена.Есть ли в этом какая-то большая логика, которую я упускаю, или это просто какое-то произвольное решение?

Ответы [ 3 ]

3 голосов
/ 22 ноября 2011

соглашение об угловых скобках используется самим интерпретатором Python, так что это больше вопрос для ... GVR?

>>> class Foo(object):
...     pass
... 
>>> f = Foo()
>>> print repr(f)
<__main__.Foo object at 0x1004ab290>
2 голосов
/ 22 ноября 2011

Имейте в виду, что eval используется не слишком часто;создание строк для него (или проверка, действительно ли они уже работают) - просто ненужные дополнительные усилия.Вставить угловые скобки, не задумываясь, гораздо проще и не дает людям идеи об использовании eval (что опасно, если вы не будете осторожны)

Другими словами, не было никакого преднамеренного решения нарушить eval(repr(x)) здесь.Обычно принято ставить угловые скобки вокруг вывода __repr__.

0 голосов
/ 22 ноября 2011

Один аргумент для угловых скобок заключается в семантике.В то время как eval(repr(2)) is 2 все время, eval(repr(23094823589710L)) is not 23094823589710L, и я не верю, что eval(repr(myinstance)) is instance будет в общем случае истинно для экземпляров mapper классов.То, поддерживаются ли идентичность и равенство таким образом, может даже зависеть от наличия уникальных ограничений или других свойств класса.

Другая проблема - это доступность класса в пространстве имен.Если конкретный класс окажется вне области действия, eval(repr(x)) вызовет NameError.

Более сложный пример: я написал свою собственную библиотечную функцию (метакласс), которая принимает имя таблицы в виде строки, динамически создает класс, используя type в качестве конструктора и mapper, который уже предоставляет методы __init__, __str__ и __repr__, и возвращает новый класс.Все такие классы имеют идентичные атрибуты __name__, поэтому невозможно поддерживать eval(repr(x)) is x или даже eval(repr(x)) == x в моей библиотечной функции.Поэтому в этих классах я использую угловые скобки для repr.

Моя ставка, по этим и, возможно, другим причинам, в документации используются угловые скобки, чтобы избежать ожидания того, что eval(repr(x)) is x всегда будет поддерживаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...