我对Python很陌生,目前我需要为SqlAlchemy类提供__repr__
。
我有一个可以接受Null
值的整数列,SqlAlchemy将其转换为None
。
例如:
class Stats(Base):
__tablename__ = "stats"
description = Column(String(2000))
mystat = Column(Integer, nullable=True)
当SqlAlchemy返回__repr__
时,在None
函数中表示“mystat”字段的正确方法是什么?
答案 0 :(得分:10)
__repr__
应返回描述该对象的字符串。如果可能,它应该是一个有效的Python表达式,其求值为一个相等的对象。这适用于内置类型,例如int
或str
:
>>> x = 'foo'
>>> eval(repr(x)) == x
True
如果那是不可能的,那么它应该是唯一描述该对象的'<...>'
字符串。默认__repr__
就是一个例子:
>>> class Foo(object):
pass
>>>
>>> repr(Foo())
'<__main__.Foo object at 0x02A74E50>'
它使用内存中的对象地址来唯一标识它。当然,地址并没有告诉我们很多关于对象的信息,因此覆盖__repr__
并返回描述对象状态的字符串很有用。
对象的状态由它包含的其他对象定义,因此将repr
包含在您的对象中是有意义的。这正是list
或dict
所做的:
>>> 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)
答案 1 :(得分:4)
我试图找到一个可以在任何SQLAlchemy对象上使用的通用__repr__
方法,并且只找到此页面。所以,我决定写我自己的,这就是我所做的:
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
,因此显示将保持一致。
答案 2 :(得分:0)
也许repr(mystat)
是你想要的?
答案 3 :(得分:0)
'Null'如果mystat是None mystat
答案 4 :(得分:0)
sqlalchemy-utils的generic_repr装饰器不是提供适合您需求的基于社区的解决方案吗?
它保留为无。
答案 5 :(得分:0)
上一个显示如何覆盖Base.__repr__
的答案正是我所需要的。谢谢!在这里,使用f字符串重新编写了Python 3.7+,并重写了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