Raf*_*afe 10 python unicode class subclass derived-class
Python打印没有使用__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'
Run Code Online (Sandbox Code Playgroud)
我不确定这是否是上述的准确近似值,只是为了比较:
>>> 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__'
Run Code Online (Sandbox Code Playgroud)
[编辑...]这听起来像获取字符串对象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
Run Code Online (Sandbox Code Playgroud)
上面的_ 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__'
Run Code Online (Sandbox Code Playgroud)
思考?
nne*_*neo 10
问题是,print不尊重__str__的unicode子类.
来自PyFile_WriteObject,使用者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;
Run Code Online (Sandbox Code Playgroud)
PyUnicode_Check(v)如果v类型是unicode 或子类,则返回true .因此,此代码直接编写unicode对象,无需咨询__str__.
请注意,子类化str和重写__str__按预期工作:
>>> class mystr(str):
... def __str__(self): return "str"
... def __repr__(self): return "repr"
...
>>> print mystr()
str
Run Code Online (Sandbox Code Playgroud)
如调用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'
Run Code Online (Sandbox Code Playgroud)
我相信这可能被解释为目前实施的Python中的一个错误.
你是子类unicode.
它永远不会打电话,__unicode__因为它已经是 unicode.这里发生的是对象被编码为stdout编码:
>>> s.encode('utf8')
'HI'
Run Code Online (Sandbox Code Playgroud)
除了它将使用直接C调用而不是.encode()方法.这是printunicode对象的默认行为.
该print声明称PyFile_WriteObject,这反过来又要求PyUnicode_AsEncodedString处理时,一个unicode物体.后者然后遵循当前编码的编码函数,并且这些函数使用Unicode C宏直接访问数据结构.你无法从Python中拦截这个.
__encode__我猜你正在寻找的是一个钩子.由于这已经是一个unicode子类,print只需要编码,不需要unicode 再次转换它,也不能将它转换为字符串而不用显式编码.您必须与Python核心开发人员合作,看看是否__encode__有意义.