Есть ли причина, по которой учебник SQLAlchemy ORM ставит угловые скобки вокруг своих значений repr?
Учебник 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 ответов:
Имейте в виду, что
evalиспользуется не слишком много; создание строк для него (или проверка, действительно ли они уже работают) - это просто ненужные дополнительные усилия. Ставить угловые скобки без раздумий намного проще, и это не дает людям идей об использованииeval(что опасно, если вы не будете осторожны).Другими словами, не было никакого сознательного решения, чтобы разорвать
eval(repr(x))здесь. Просто принято ставить угловые скобки вокруг вывода__repr__.
Соглашение об угловых скобках используется самим интерпретатором Python, так что это скорее вопрос ...ГВР ?
>>> class Foo(object): ... pass ... >>> f = Foo() >>> print repr(f) <__main__.Foo object at 0x1004ab290>
Один из аргументов в пользу угловых скобок заключается в семантике. В то время как
eval(repr(2)) is 2все времяeval(repr(23094823589710L)) is not 23094823589710L, и я не верю, чтоeval(repr(myinstance)) is instanceбудет истинно вообще для экземпляровmapperклассов. Поддерживается ли идентичность и равенство таким образом, может даже зависеть от наличия уникальных ограничений или других свойств класса.Другой проблемой является доступность класса в пространстве имен. Если определенный класс не попадает в область видимости,
eval(repr(x))вызоветNameError.A более сложный пример: я написал свою собственную библиотечную функцию (метакласс), которая принимает имя таблицы в виде строки, динамически создает класс, используя
typeв качестве конструктора иmapper, который уже предоставляет__init__,__str__и__repr__методы, и возвращает новый класс. Все такие классы имеют одинаковые атрибуты__name__, поэтому невозможно поддерживатьeval(repr(x)) is xили дажеeval(repr(x)) == xв моей библиотечной функции. Поэтому я использую угловые скобки дляreprв этих классах.Моя ставка заключается в том, что по этим причинам и возможно, в других документах используются угловые скобки, чтобы избежать ожидания, что
eval(repr(x)) is xвсегда будет поддерживаться.
Comments