5

我对 Python 很陌生,目前我需要__repr__一个 SqlAlchemy 类。我有一个可以接受Null值的整数列,SqlAlchemy 将其转换为None. 例如:

class Stats(Base):
   __tablename__ = "stats"
   description = Column(String(2000))
   mystat = Column(Integer, nullable=True)

__repr__当 SqlAlchemy 返回时,在函数中表示“mystat”字段的正确方法是什么None

4

6 回答 6

11

__repr__应该返回一个描述对象的字符串。如果可能,它应该是一个有效的 Python 表达式,计算结果为相等的对象。int这对于像or这样的内置类型是正确的str

>>> x = 'foo'
>>> eval(repr(x)) == x
True

如果这不可能,它应该是一个'<...>'唯一描述对象的字符串。默认__repr__是这样的一个例子:

>>> class Foo(object):
        pass
>>>
>>> repr(Foo())
'<__main__.Foo object at 0x02A74E50>'

它使用对象在内存中的地址来唯一标识它。当然,地址并没有告诉我们太多关于对象的信息,因此覆盖__repr__并返回描述对象状态的字符串很有用。

对象的状态由它包含的其他对象定义,因此将它们包含在您的状态中是有意义的repr。这正是做什么listdict做什么:

>>> repr(['bar', Foo()])
"['bar', <__main__.Foo object at 0x02A74710>]"

在您的情况下,状态在您的Column属性中,因此您想使用它们的repr. 您可以%r为此使用格式,它插入一个repr()参数:

def __repr__(self):
    return '<Stats: description=%r, mystat=%r>' % (self.description, self.mystat)

使用新格式的等效项:

def __repr__(self):
    return '<Stats: description={0.description!r}, mystat={0.mystat!r}>'.format(self)
于 2011-10-13T15:55:26.180 回答
8

我试图找到一个__repr__可以在任何 SQLAlchemy 对象上使用的通用方法,但只找到了这个页面。所以,我决定自己写,这就是我所做的:

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

if __debug__:
    # monkey-patch in useful repr() for all objects, but only in dev
    def tablerepr(self):
        return "<{}({})>".format(
            self.__class__.__name__,
            ', '.join(
                ["{}={}".format(k, repr(self.__dict__[k]))
                    for k in sorted(self.__dict__.keys())
                    if k[0] != '_']
            )
        )
    Base.__repr__ = tablerepr

这扩展了Base类以打印出特定实例的内容。因此,现在我创建的每个扩展 的对象Base都将有一个__repr__方法,该方法不仅可以打印类名和实例哈希。

编辑:我添加了一个if __debug__,因为此更改可能会导致信息泄漏,您可能不希望在生产环境中泄漏。我还添加了一个sorted,所以显示将是一致的。

于 2013-04-10T15:08:02.290 回答
3

sqlalchemy-utils 的generic_repr装饰器不是提供了适合您需求的基于社区的解决方案吗?

它将它保留为无。

于 2018-05-22T16:30:12.227 回答
0

也许repr(mystat)是你想要的?

于 2011-10-13T15:36:01.177 回答
0

'Null' 如果 mystat 是 None 否则 mystat

于 2011-10-13T15:40:29.023 回答
0

先前显示如何覆盖的答案Base.__repr__正是我所需要的。谢谢!在这里,它使用 Python 3.7+ 的 f-strings 重写并覆盖了 flask-sqlalchemy db.Model

def override_default_repr(self):
    class_name = self.__class__.__name__
    attribs = ", ".join(
        [
            f"{k}={self.__dict__[k]!r}"
            for k in sorted(self.__dict__.keys())
            if k[0] != "_"
        ]
    )
    return f"<{class_name}({attribs})>"

db.Model.__repr__ = override_default_repr
于 2020-06-04T03:13:16.470 回答