python字符串插值
什么会产生以下行为python字符串插值,python,string,string-interpolation,Python,String,String Interpolation,什么会产生以下行为 >>> print str(msg) my message >>> print unicode(msg) my message 但是: 更多信息: 我的msg对象继承自unicode 方法\uuuu str\uuuu/\uuuuunicode\uuuu/\uuuuuu repr\uuuu方法被重写以返回字符串'my message' msg对象是用字符串“另一条消息”初始化的 这是在Python2.5上运行的 变量msg在测试之间未更改
>>> print str(msg)
my message
>>> print unicode(msg)
my message
但是:
更多信息:
- 我的
对象继承自msg
unicode
- 方法
/\uuuu str\uuuu
/\uuuuunicode\uuuu
方法被重写以返回字符串\uuuuuu repr\uuuu
'my message'
对象是用字符串msg
初始化的“另一条消息”
- 这是在Python2.5上运行的
- 变量
在测试之间未更改msg
- 这实际上是真正的doctest,它给出了这些结果
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()
- zope.I18N消息-3.4.3()
- 添加/更新了被重写的方法的名称
- 添加了更多信息(python版本和次要信息)
- 更新了一些错误信息(“msg”的类基于“unicode”类而不是“basestring”)
- 添加了所用类的实际实现
Include/unicodeobject.h
包含以下to行(我的(有些旧)签出中的编号436-7):
这在格式化代码中被广泛使用,据我所知,这意味着在字符串格式化过程中,从unicode
继承的任何对象都将被访问,以便可以直接使用其unicode字符串缓冲区,而无需调用任何Python方法。就性能而言,这是好的,我敢肯定(并且非常符合Juergen在对这个答案的评论中的猜测)
对于OP的问题,这可能意味着只有当Anurag Uniyal的包装类思想对于这个特定用例是可以接受的时候,才能按照OP希望的方式工作。如果不是,我现在想到的唯一一件事就是将此类对象包装在str
/unicode
中,将它们插入字符串中的任何位置。。。啊。(我真诚地希望我错过了一个更干净的解决方案,有人会在一分钟内指出!)
(更新:这是在OP包含他的类的代码前一分钟发布的,但我还是把它留在这里(1)为了猜测/初步尝试在代码下面解释,(2)为了一个简单的例子,如何产生这种行为(Anurag Uniyal后来提供了另一个直接调用unicode的构造函数,而不是通过super进行调用),(3)希望以后能够编辑一些内容,帮助OP获得所需的行为。) 下面是一个类的示例,它的实际工作方式与OP所描述的类似(Python 2.6.4,它确实生成了一个弃用警告--
/usr/bin/ipython:3:弃用警告:object.\uuu init\uuuuu()不接受任何参数
):
IPython中的几个交互:
In [12]: print(Foo("asdf"))
asdf
In [13]: str(Foo("asdf"))
Out[13]: 'str msg'
In [14]: print str(Foo("asdf"))
-------> print(str(Foo("asdf")))
str msg
In [15]: print(str(Foo("asdf")))
str msg
In [16]: print('%s' % Foo("asdf"))
asdf
显然,字符串插值将此对象视为unicode
的一个实例(直接调用的unicode
实现),而其他函数将其视为Foo
的一个实例。我真的不知道这在内部是如何发生的,为什么它会这样工作,以及它是一个bug还是一个功能
至于如何修复OP的对象…好吧,我怎么知道没有看到它的代码???给我代码,我保证会考虑它!好的,我正在考虑它…到目前为止还没有想法。所以问题是类喜欢下面的行为怪异
class Msg(unicode):
def __init__(self, s):
unicode.__init__(self, s)
__unicode__ = __repr__ = __str__ = lambda self: "my message"
msg = Msg("another message")
print str(msg)
print unicode(msg)
print "%s"%msg
这张照片
my message
my message
another message
我不知道为什么会发生这种情况,也不知道如何解决它,但包装味精是一个非常粗糙的尝试,但不确定它是否有助于解决OP的问题
class MsgX(object):
def __init__(self, s):
self._msg = Msg(s)
__unicode__ = __repr__ = __str__ = lambda self: repr(self._msg)
msg = MsgX("another message")
print str(msg)
print unicode(msg)
print "%s"%msg
输出:
my message
my message
my message
我想你的问题是你试图扩展一个内置的。Magic\uuu
方法不会被内置调用。我想你必须做一些包装和委托,就像这样(未经测试)(也许Anurag打败了我):
更新1-似乎\uuu
方法确实会为内置的子类调用
>>> class Z(int):
... def __add__(self,other): return self*other
... def __str__(self): return "***"
...
>>> a = Z(100)
>>> a + 2
200
>>> a
100
>>> str(a)
'***'
>>> "%s" % a
'***'
因此,肯定存在一些不一致性…@extranon:这是python 2.x:print
是一个语句、basestring、unicode!在print
s之间更改msg
变量的值可以解释这一点it@vaab,msg的类实现是绝密的吗?否则我想看看it@vaab,我为我的错误道歉这对我来说似乎是Python内部的一个bug,所以我会在Python的跟踪器中打开一个bug(使用下面类似Michal的简化代码)。作为一种在等待固定Python版本时的错误解决方法,在我看来Paul的想法是正确的。在我看来,print提供了一些快捷方式——我认为是为了加快速度。Python有(相对较快的)内部接口和(相对较慢的)外部接口。我猜,有人试图避免开销…@Juergen:现在在答案中包含了一些关于源代码的信息…看起来你肯定是对的。@Michal:谢谢你提供的信息!Python作为一个系统是相当干净的,但是(据我所知,也看到了一点)有时一些捷径是在内部建立的,这样可以获得很大的速度优势。在我看来,这是可以的,因为这些捷径在99%的情况下都是不可见的…在
my message
my message
another message
class MsgX(object):
def __init__(self, s):
self._msg = Msg(s)
__unicode__ = __repr__ = __str__ = lambda self: repr(self._msg)
msg = MsgX("another message")
print str(msg)
print unicode(msg)
print "%s"%msg
my message
my message
my message
class Message(object):
def __init__(self, strvalue, domain, default='my message'):
self.msg = zope.i18nmessageid.Message(strvalue,domain,default)
def __getattr__(self,attr):
return getattr(self.msg,attr)
def __repr__(self):
return repr(zope.i18n.interpolate(self.msg.default, self.msg.mapping))
def __str__(self):
return zope.i18n.interpolate(self.msg.default, self.msg.mapping)
def __unicode__(self):
return zope.i18n.interpolate(self.msg.default, self.msg.mapping)
>>> class Z(int):
... def __add__(self,other): return self*other
... def __str__(self): return "***"
...
>>> a = Z(100)
>>> a + 2
200
>>> a
100
>>> str(a)
'***'
>>> "%s" % a
'***'