Python print不使用__repr __,__ unicode__或__str__作为unicode子类?

时间:2013-03-28 16:51:51

标签: python class unicode subclass derived-class

Python print在打印时没有使用__repr____unicode____str__作为我的unicode子类。关于我做错了什么的线索?

这是我的代码:

使用Python 2.5.2(r252:60911,2009年10月13日,14:11:59)

>>> class MyUni(unicode):
...     def __repr__(self):
...         return "__repr__"
...     def __unicode__(self):
...         return unicode("__unicode__")
...     def __str__(self):
...         return str("__str__")
...      
>>> s = MyUni("HI")
>>> s
'__repr__'
>>> print s
'HI'

我不确定这是否是上述的准确近似值,只是为了比较:

>>> class MyUni(object):
...     def __new__(cls, s):
...         return super(MyUni, cls).__new__(cls)
...     def __repr__(self):
...         return "__repr__"
...     def __unicode__(self):
...         return unicode("__unicode__")
...     def __str__(self):
...         return str("__str__")
...
>>> s = MyUni("HI")
>>> s
'__repr__'
>>> print s
'__str__'

[EDITED ...] 这听起来像获取字符串对象isinstance(instance,basestring)并提供对unicode返回值的控制的最佳方法,并且使用unicode repr是...

>>> class UserUnicode(str):
...     def __repr__(self):
...         return "u'%s'" % super(UserUnicode, self).__str__()
...     def __str__(self):
...         return super(UserUnicode, self).__str__()
...     def __unicode__(self):
...         return unicode(super(UserUnicode, self).__str__())
...
>>> s = UserUnicode("HI")
>>> s
u'HI'
>>> print s
'HI'
>>> len(s)
2

上面的 _ str _ _ repr _ 上面没有添加任何内容,但想法是明确地显示一个模式,根据需要进行扩展。

只是为了证明这种模式可以控制:

>>> class UserUnicode(str):
...     def __repr__(self):
...         return "u'%s'" % "__repr__"
...     def __str__(self):
...         return "__str__"
...     def __unicode__(self):
...         return unicode("__unicode__")
... 
>>> s = UserUnicode("HI")
>>> s
u'__repr__'
>>> print s
'__str__'

思想?

2 个答案:

答案 0 :(得分:10)

问题是print不尊重__str__子类的unicode

来自print,由int PyFile_WriteObject(PyObject *v, PyObject *f, int flags) { ... if ((flags & Py_PRINT_RAW) && PyUnicode_Check(v) && enc != Py_None) { char *cenc = PyString_AS_STRING(enc); char *errors = fobj->f_errors == Py_None ? "strict" : PyString_AS_STRING(fobj->f_errors); value = PyUnicode_AsEncodedString(v, cenc, errors); if (value == NULL) return -1; 使用:

PyUnicode_Check(v)
如果v的类型为unicode 或子类,则

__str__会返回true。因此,此代码直接编写unicode对象,而无需咨询str

请注意,子类__str__和覆盖>>> class mystr(str): ... def __str__(self): return "str" ... def __repr__(self): return "repr" ... >>> print mystr() str 按预期工作:

str

明确调用unicode>>> class myuni(unicode): ... def __str__(self): return "str" ... def __repr__(self): return "repr" ... def __unicode__(self): return "unicode" ... >>> print myuni() >>> str(myuni()) 'str' >>> unicode(myuni()) u'unicode'

{{1}}

我认为这可能被解释为目前已实施的Python中的错误。

答案 1 :(得分:6)

您正在继承unicode

它永远不会调用__unicode__,因为它已经是 unicode。这里发生的是对象编码stdout编码:

>>> s.encode('utf8')
'HI'

除了它将使用直接C调用而不是.encode()方法。这是unicode对象的print的默认行为。

print语句会调用PyFile_WriteObjectPyUnicode_AsEncodedString会在处理unicode对象时调用Unicode C macros。后者然后推迟到当前编码的 编码函数,并且这些函数使用{{3}}直接访问数据结构。你无法从Python中拦截它。

我猜你正在寻找的是__encode__钩子。由于这已经是unicode子类,print只需要编码,而不是再次将其转换为unicode ,也不能将其转换为字符串而不进行编码明确地说。您必须与Python核心开发人员合作,看看__encode__是否有意义。