Python和None

Python和None,python,sqlalchemy,repr,Python,Sqlalchemy,Repr,我对Python非常陌生,目前我需要一个SqlAlchemy类的\uuu repr\uuu。 我有一个整数列,可以接受Null值,SqlAlchemy将其转换为None。 例如: class Stats(Base): __tablename__ = "stats" description = Column(String(2000)) mystat = Column(Integer, nullable=True) 当SqlAlchemy返回None时,在\uuuu repr\u

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

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

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

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

如果mystat不是其他mystat,则“Null”应该返回一个描述对象的字符串。如果可能的话,它应该是一个有效的Python表达式,其计算结果应该是一个相等的对象。这适用于内置类型,如
int
str

>>> x = 'foo'
>>> eval(repr(x)) == x
True
如果不可能,它应该是唯一描述对象的
'
字符串。默认的
\uuuu repr\uuuu
就是一个例子:

>>> class Foo(object):
        pass
>>>
>>> repr(Foo())
'<__main__.Foo object at 0x02A74E50>'
在您的情况下,状态位于
属性中,因此您希望使用它们的
repr
。您可以为此使用
%r
格式,它会插入参数的
repr()

def __repr__(self):
    return '<Stats: description=%r, mystat=%r>' % (self.description, self.mystat)
def\uuu repr\uu(自):
返回“”%(self.description,self.mystat)
使用新格式的等效文件:

def __repr__(self):
    return '<Stats: description={0.description!r}, mystat={0.mystat!r}>'.format(self)
def\uuu repr\uu(自):
返回“”。格式(自身)

我试图找到一个通用的
\uuuuu repr\uuuu
方法,该方法可用于任何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
来自sqlalchemy.ext.declarative import declarative\u base
Base=声明性_Base()
如果调试:
#猴子补丁在repr()中适用于所有对象,但仅在dev中
def表格报告(自我):
返回“”格式(
self.\uuuuu类\uuuuuuu名\uuuuuuuuu,
“,”加入(
[“{}={}”。格式(k,repr(self.\uu dict\uuu[k]))
对于排序中的k(self.\u dict.\u.keys())
如果k[0]!='\']
)
)
基本报告=表格报告
这扩展了
Base
类以打印出特定实例的内容。因此,现在我创建的每个扩展
基的对象都将有一个
\uuuu repr\uuuu
方法,该方法打印的不仅仅是类名和实例哈希

EDIT:我添加了一个
if\uuuuu debug\uuuu
,因为此更改可能会导致您不希望在生产环境中泄漏的信息泄漏。我还添加了一个排序的
,这样显示将保持一致。

sqlalchemy utils的装饰师不是提供了一个基于社区的解决方案来满足您的需要吗


它保留为无。

前面的答案显示了如何覆盖
基。_urepr_uu
正是我所需要的。非常感谢。在这里,它是用Python3.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
def覆盖默认报告(self):
class\u name=self.\u class\u.\u name__
attribs=“,”。加入(
[
f“{k}={self.\u dict\u[k]!r}”
对于排序中的k(self.\u dict.\u.keys())
如果k[0]!=“\u0”
]
)
返回f“”
db.Model.\uuuu repr\uuuu=覆盖\u默认值\u repr

The _repr__;()只返回python对象的字符串表示形式。我不确定是否有一种“正确”的方法来实现它。您确实了解,在您的代码示例中,您正在创建类属性,而不是实例属性,对吗?@KarlKnechtel现在我在线搜索了,我知道了,谢谢。这就是为什么我写我是Python新手:)哇,谢谢。如果我们不能返回“返回创建对象的代码”,我就错过了
repr
的尖括号(即
<…>
)约定。还要注意,
str
返回到
repr
。这是正确的答案。不幸的是,所有其他答案都早于此解决方案,但这正是人们现在应该使用的。然而,将该装饰程序包装在检查开发环境以防止生产中的数据泄漏的东西中可能是有益的。
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