python 字符串插值
什么会产生以下行为?
>>> print str(msg)
my message
>>> print unicode(msg)
my message
但是:
>>> print '%s' % msg
another message
更多信息:
- 我的
msg
对象继承自unicode
。 __str__
/__unicode__
/__repr__
方法被重写以返回字符串'my message'
。msg
对象是用字符串'another message'
初始化的。- 这是在 python 2.5 上运行的,
- 变量
msg
在测试之间没有改变, - 这实际上是真正给出这些结果的真正的文档测试。
我想要一个与此文档测试相匹配的解决方案,并且尽量减少麻烦(特别是在实际继承方面):
>>> print '%s' % msg
my message
感谢所有建议。
我不认为这会有更多帮助,但对于好奇的读者(和喜欢冒险的Python专家)来说,这是该对象的实现:
class Message(zope.i18nmessageid.Message):
def __repr__(self):
return repr(zope.i18n.interpolate(self.default, self.mapping))
def __str__(self):
return zope.i18n.interpolate(self.default, self.mapping)
def __unicode__(self):
return zope.i18n.interpolate(self.default, self.mapping)
这就是我们创建对象msg的方式:
>>> msg = Message('another message', 'mydomain', default='my message')
Zope包版本和使用的代码是:
- zope.i18n-3.4。 0 (interpolation() 方法代码 )
- zope.i18nmessageid-3.4.3 (消息类代码)
编辑信息:
- 添加/更新了被覆盖的方法的名称
- 添加了一些更多信息(python 版本和次要版本) info)
- 更新了一些错误信息(`msg`类基于`unicode`类而不是`basestring`)
- 添加了所使用的类的实际实现
What could generate the following behavior ?
>>> print str(msg)
my message
>>> print unicode(msg)
my message
But:
>>> print '%s' % msg
another message
More info:
- my
msg
object is inherited fromunicode
. - the methods
__str__
/__unicode__
/__repr__
methods were overridden to return the string'my message'
. - the
msg
object was initialised with the string'another message'
. - this is running on python 2.5
- the variable
msg
was not changed between the tests - this is actually real doctest that is really giving these results.
I would like an solution that matches this doctest, with minimal fuss (especially around the actual inheritance):
>>> print '%s' % msg
my message
Thanks for all suggestions.
I don't feel this will help more, but for curious readers (and adventurous pythonist), here's the implementation of the object:
class Message(zope.i18nmessageid.Message):
def __repr__(self):
return repr(zope.i18n.interpolate(self.default, self.mapping))
def __str__(self):
return zope.i18n.interpolate(self.default, self.mapping)
def __unicode__(self):
return zope.i18n.interpolate(self.default, self.mapping)
This is how we create the object msg:
>>> msg = Message('another message', 'mydomain', default='my message')
Zope packages version and code used are:
- zope.i18n-3.4.0 (interpolation() method code )
- zope.i18nmessageid-3.4.3 (Message class code)
EDIT INFO:
- added/updated the names of the methods that were overriden
- added some more info (python version, and minor info)
- updated some wrong info (the class of `msg` is based on `unicode` class and not `basestring`)
- added the actual implementation of the class used
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
更新2:请找到原始答案,包括水平条下方展示 OP 描述的行为的类的简单示例。至于我在查询 Python 源代码(v. 2.6.4)的过程中能够推测出的内容:
文件
Include/unicodeobject.h
包含以下行(第 436-7 行)在我的(有点旧的)结帐中):这在格式化代码中随处可见,据我所知,这意味着在字符串格式化期间,任何继承自
unicode
的对象都会以便可以直接使用其 unicode 字符串缓冲区,而无需调用任何 Python 方法。我确信就性能而言这是好的(并且非常符合于尔根在对此答案的评论中的猜想)。对于OP的问题,这可能意味着只有当Anurag Uniyal的包装类想法对于这个特定的用例来说是可以接受的时候,才能让事情按照OP希望的方式工作。如果不是,我现在唯一想到的就是将此类的对象包装在
str
/unicode
中,无论它们插入到字符串中...啊。 (我真诚地希望我只是错过了一个更干净的解决方案,有人会在一分钟内指出!)(更新:这是在 OP 包含他的类的代码之前大约一分钟发布的,但是我无论如何,我把它留在这里(1)用于猜测/初步尝试在代码下面进行解释,(2)用于一个如何产生此行为的简单示例(Anurag Uniyal 此后提供了另一个调用
unicode 的构造函数直接,而不是通过
super
),(3)希望以后能够编辑某些内容以帮助 OP 获得所需的行为。)这是一个示例类的工作方式实际上与OP描述的类似(Python 2.6.4,它确实产生了弃用警告 -
/usr/bin/ipython:3: DeprecationWarning: object.__init__() gets noparameter
) :IPython 中的一些交互:
显然字符串插值将此对象视为
unicode
的实例(直接调用__str__
的unicode
实现),而其他函数将其视为 Foo 的实例。我真的不知道这是如何在内部发生的以及为什么它会这样工作以及它是一个错误还是一个功能。至于如何修复OP的对象...好吧,如果不看到它的代码我怎么知道???给我代码,我保证会考虑一下!好吧,我正在考虑......到目前为止还没有想法。Update 2: Please find the original answer, including a simple example of a class exhibiting the behaviour described by the OP, below the horizontal bar. As for what I was able to surmise in the course of my inquiry into Python's sources (v. 2.6.4):
The file
Include/unicodeobject.h
contains the following to lines (nos. 436-7 in my (somewhat old) checkout):This is used all over the place in the formatting code, which, as far as I can tell, means that during string formatting, any object which inherits from
unicode
will be reached into so that its unicode string buffer may be used directly, without calling any Python methods. Which is good as far as performance is concerned, I'm sure (and very much in line with Juergen's conjecture in a comment on this answer).For the OP's question, this probably means that making things work the way the OP would like them to may only be possible if something like Anurag Uniyal's wrapper class idea is acceptable for this particular use case. If it isn't, the only thing which comes to my mind now is to wrap objects of this class in
str
/unicode
wherever their being interpolated into a string... ugh. (I sincerely hope I'm just missing a cleaner solution which someone will point out in a minute!)(Update: This was posted about a minute before the OP included the code of his class, but I'm leaving it here anyway (1) for the conjecture / initial attempt at an explanation below the code, (2) for a simple example of how to produce this behaviour (Anurag Uniyal has since provided another one calling
unicode
's constructor directly, as opposed to viasuper
), (3) in hope of later being able to edit in something to help the OP in obtaining the desired behaviour.)Here's an example of a class which actually works like what the OP describes (Python 2.6.4, it does produce a deprecation warning --
/usr/bin/ipython:3: DeprecationWarning: object.__init__() takes no parameters
):A couple of interactions in IPython:
Apparently string interpolation treats this object as an instance of
unicode
(directly calling theunicode
implementation of__str__
), whereas the other functions treat it as an instance ofFoo
. How this happens internally and why it works like this and whether it's a bug or a feature, I really don't know.As for how to fix the OP's object... Well, how would I know without seeing its code??? Give me the code and I promise to think about it!Ok, I'm thinking about it... No ideas so far.所以问题是像下面的类的行为很奇怪
,
我不确定为什么会发生这种情况或如何修复它,但通过包装 Msg 进行了非常粗略的尝试,但不确定它是否有助于OP的问题
输出:
So problem is class like to something below behaves weirdly
this prints
I am not sure why this happens or how to fix it, but a very crude attempt by wrapping Msg, but not sure it will help in OP's problem
output:
我认为你的问题是你正在尝试扩展内置的。内置函数不会调用魔术
__
方法。我认为你必须做某种包装和委托,就像这样(未经测试)(也许 Anurag 打败了我):更新 1 - 看起来内置函数的子类会调用
__
方法 do所以肯定存在一些不一致的情况......
I think your problem is that you are trying to extend a built-in. Magic
__
methods don't get called for builtins. I think you will have to do some kind of wrap-and-delegate, like this (untested) (maybe Anurag beat me to the punch):Update 1 - it seems that
__
methods do get called for subclasses of builtinsSo there is definitely some inconsistency going on...