python模块可以有__repr__吗?

Posted

技术标签:

【中文标题】python模块可以有__repr__吗?【英文标题】:Can a python module have a __repr__? 【发布时间】:2022-01-13 17:06:51 【问题描述】:

python 模块可以有 __repr__ 吗?我们的想法是这样做:

import mymodule
print mymodule

编辑:精度:我的意思是 用户定义的 repr!

【问题讨论】:

【参考方案1】:

简答:基本上答案是否定的。

但是您不能使用文档字符串找到您正在寻找的功能吗?

testmodule.py
""" my module test does x and y
"""
class myclass(object):
    ...
test.py
import testmodule
print testmodule.__doc__

长答案:

您可以在模块级别定义自己的__repr__(只需提供def __repr__(...),但您必须这样做:

import mymodule
print mymodule.__repr__() 

获得你想要的功能。

看看下面的 python shell 会话:

>>> import sys                 # we import the module
>>> sys.__repr__()               # works as usual
"<module 'sys' (built-in)>"
>>> sys.__dict__['__repr__']     # but it's not in the modules __dict__ ?
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: '__repr__'
>>> sys.__class__.__dict__['__repr__'] # __repr__ is provided on the module type as a slot wrapper
<slot wrapper '__repr__' of 'module' objects>
>>> sys.__class__.__dict__['__repr__'](sys) # which we should feed an instance of the module type
"<module 'sys' (built-in)>"

所以我认为问题出在这些slot wrapper objects 中,它们(从链接中可以阅读的内容)绕过了通常的“python”查找项目属性的方式。

对于这些类方法,CPython 返回指向这些对象上相应方法的 C 指针(然后将其包装在插槽包装器对象中,以便从 python 端调用)。

【讨论】:

我很想听听 Alex Martelli 的解释 ;-) Christophe:我会为您省去麻烦,他告诉我原因,请参阅 ***.com/questions/1060796/callable-modules 和 ***.com/questions/1725515/…。【参考方案2】:

你可以达到这个效果——如果你愿意转向原力的黑暗面。

将此添加到 mymodule.py:

import sys

class MyReprModule(mymodule.__class__):
  def __init__(self, other):
    for attr in dir(other):
      setattr(self, attr, getattr(other, attr))

  def __repr__(self):
    return 'ABCDEFGHIJKLMNOQ'

# THIS LINE MUST BE THE LAST LINE IN YOUR MODULE
sys.modules[__name__] = MyReprModule(sys.modules[__name__])

你瞧:

>>> import mymodule
>>> print mymodule
ABCDEFGHIJKLMNOQ

我依稀记得,在以前的类似邪恶黑客尝试中,在设置特殊属性(如 __class__)时遇到了麻烦。我在测试时没有遇到这个问题。如果遇到该问题,只需捕获异常并跳过该属性。

【讨论】:

这是最好的答案,可惜排名不高。此外,恕我直言,这并不是真正的“邪恶”黑客攻击:您在 sys 级别更改的唯一值是模块本身的名称。我觉得模块的所有者应该能够安全地调整与该模块相关的任何内容。【参考方案3】:

模块可以具有__repr__ 函数,但在获取模块表示时不会调用它。

所以不,你不能做你想做的事。

【讨论】:

【参考方案4】:

事实上,许多模块确实[有一个__repr__]!

>>> import sys
>>> print(sys)
<module 'sys' (built-in)>    #read edit, however, this info didn't come from __repr__ !

也可以尝试dir(sys) 看看__repr__ 是否与__name__ 等一起出现。

编辑__repr__ 似乎可以在 Python 3.0 及更高版本的模块中找到。 正如 Ned Batchelder 所指出的,Python 在打印出 a 模块时使用此方法。 (重新分配 repr 属性的快速实验表明...)

【讨论】:

repr 不在我的系统属性中(python 2.6.2) 对于它的价值,我在我的 Python (2.5.1) 中找到了 sys.__repr__,但我确实认为这不是用 print(sys) 打印出来的。 在 python 2.6.2 中 __repr__ 不在 dir(sys)sys.__dict__ 中。但是,它是 sys.__class__.__dict__' (repr' of 'module' objects>` 中的有效键。【参考方案5】:

不,因为__repr__ 是一个特殊的方法(我称之为capability),它只会在类中查找。您的模块只是该模块类型的另一个实例,因此无论您如何定义__repr__,它都不会被调用!

【讨论】:

以上是关于python模块可以有__repr__吗?的主要内容,如果未能解决你的问题,请参考以下文章

python_魔法方法:__str__()和__repr__()

我可以为类而不是实例定义 __repr__ 吗? [复制]

对于自定义 Python 类,哪个 __repr__ 更好?

Python __repr__ 和无

Python详解类的 __repr__() 方法

python之反射和内置函数__str____repr__