【问题标题】:How to Understand and Parse the Default Python Object Representations如何理解和解析默认 Python 对象表示
【发布时间】:2013-11-14 07:34:50
【问题描述】:

当您在 Python 中打印一个对象,而 __repr____str__ 不是由用户定义时,Python 会将对象转换为字符串表示,用尖括号分隔...

<bound method Shell.clear of <Shell object at 0x112f6f350>>

问题是在 Web 浏览器中以字符串形式呈现此内容,其中还包含必须正常呈现的 HTML。浏览器显然被尖括号弄糊涂了。

我正在努力寻找有关这些表示是如何形成的任何信息,如果它们有名称的话。

对于没有定义__repr__ 方法的所有 对象,是否可以通过覆盖object 类的__repr__ 来更改Python 将对象表示为字符串的方式?

那么,如果 Python 通常会返回 "&lt;Foo object at 0x112f6f350&gt;",那么有什么钩子可以让它返回 "{Foo object at {0x112f6f350}}" 或其他任何东西,而无需直接修改 Foo 和其他所有类?

【问题讨论】:

  • 转义有XML含义的字符怎么样?
  • 它需要将"&lt;em&gt;&lt;Shell object at 0x112f6f350&gt;&lt;/em&gt;" 之类的东西渲染为Shell repr,用斜体表示。
  • 我猜想转义不在实际 HTML 元素列表中的所有内容可能会起作用。我仍然宁愿避免解析字符串。很乱。 Python 中必须有某种方法可以连接到 __repr__ 方法或其他东西。如果能够基于self 覆盖__repr__ 默认的工作方式,以语法高亮对象表示并提取文档字符串等,那就太好了。
  • 除了将元类注入每个类或提供提供__repr__ 实现的基类(包括提供替代内置在object)。一个更好的解决方案是使用一个不错的模板库,在生成 HTML 时自动转义尖括号。
  • @CarlSmith:在某些时候你的对象是对象,此时调用escape(repr(obj)) 而不是repr(obj)。或者只是使用 Marijin 建议的 HTML 模板库

标签: python built-in repr


【解决方案1】:

您可以使用__builtin__s(在导入任何内容之前)。我发现替换 __builtin__.repr 确实不起作用,但替换 __builtin__.object 可以。

这是如何做到的。假设您有一个定义类的模块:

# foo.py
class Foo(object):
    pass

在您的 main 脚本中,执行:

# main.py
import __builtin__

class newobject(object):
    def __repr__(self):
        return '{%s object at {%s}}' % (self.__class__.__name__, hex(id(self)))

__builtin__.object = newobject

from foo import Foo

foo = Foo()
print '%r' % foo

打印:

{Foo object at {0x100400010}}

注意,您已将 bound method 作为您想要处理的示例,但绑定方法 do 定义了 __repr__,因此我猜您并不真正想要影响他们的解决方案。 (查看object().__repr__.__repr__

【讨论】:

  • 这回答了问题的赏金部分,但我强烈建议不要使用这种解决方案。无法知道这会产生什么副作用(例如,某些代码可能依赖于 __repr__ 逻辑值)。
  • @Krumelur 我同意。在我看来,您的评论更多的是关于问题而不是答案。问题是如何做到这一点。我同意所有的 cmets 说它可能不应该完成。
  • 我知道这很危险,但这没关系。一切都是为了找到钩子。这是一个很好的答案,尽管 Krumelur 的评论是完全有效的 (+1)。
【解决方案2】:

他们不是我的对象。这是一个外壳,所以用户将能够打印他们喜欢的任何东西。如果他们在基于浏览器的客户端中打印 3 个 Foos 的列表,他们不应该得到三个损坏的 [不可见] HTML 元素的列表。我正在寻找一种调整 Python 的方法,以便在进行调整后表示的所有对象都以与默认值不同的方式呈现。

在这种情况下,您可以更改sys.displayhook()

import sys
from cgi import escape
try:
    import __builtin__ as builtins
except ImportError: # Python 3
    import builtins

def html_displayhook(value):
    if value is None:
        return
    text = escape(repr(value)) # <-- make html-safe text
    sys.stdout.write(text)
    sys.stdout.write("\n")
    builtins._ = value   

sys.displayhook = html_displayhook

默认情况下,它会打印 html 安全的对象表示形式,并且不会阻止用户打印原始 html(如果他们喜欢的话)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 2023-03-27
    相关资源
    最近更新 更多