CofeehousePy/nlpfr/nltk/test/compat.doctest

135 lines
3.8 KiB
Plaintext

=========================================
NLTK Python 2.x - 3.x Compatibility Layer
=========================================
NLTK comes with a Python 2.x/3.x compatibility layer, nltk.compat
(which is loosely based on `six <http://packages.python.org/six/>`_)::
>>> from nltk import compat
>>> compat.PY3
False
>>> # and so on
@python_2_unicode_compatible
----------------------------
Under Python 2.x ``__str__`` and ``__repr__`` methods must
return bytestrings.
``@python_2_unicode_compatible`` decorator allows writing these methods
in a way compatible with Python 3.x:
1) wrap a class with this decorator,
2) define ``__str__`` and ``__repr__`` methods returning unicode text
(that's what they must return under Python 3.x),
and they would be fixed under Python 2.x to return byte strings::
>>> from nltk.compat import python_2_unicode_compatible
>>> @python_2_unicode_compatible
... class Foo(object):
... def __str__(self):
... return u'__str__ is called'
... def __repr__(self):
... return u'__repr__ is called'
>>> foo = Foo()
>>> foo.__str__().__class__
<type 'str'>
>>> foo.__repr__().__class__
<type 'str'>
>>> print(foo)
__str__ is called
>>> foo
__repr__ is called
Original versions of ``__str__`` and ``__repr__`` are available as
``__unicode__`` and ``unicode_repr``::
>>> foo.__unicode__().__class__
<type 'unicode'>
>>> foo.unicode_repr().__class__
<type 'unicode'>
>>> unicode(foo)
u'__str__ is called'
>>> foo.unicode_repr()
u'__repr__ is called'
There is no need to wrap a subclass with ``@python_2_unicode_compatible``
if it doesn't override ``__str__`` and ``__repr__``::
>>> class Bar(Foo):
... pass
>>> bar = Bar()
>>> bar.__str__().__class__
<type 'str'>
However, if a subclass overrides ``__str__`` or ``__repr__``,
wrap it again::
>>> class BadBaz(Foo):
... def __str__(self):
... return u'Baz.__str__'
>>> baz = BadBaz()
>>> baz.__str__().__class__ # this is incorrect!
<type 'unicode'>
>>> @python_2_unicode_compatible
... class GoodBaz(Foo):
... def __str__(self):
... return u'Baz.__str__'
>>> baz = GoodBaz()
>>> baz.__str__().__class__
<type 'str'>
>>> baz.__unicode__().__class__
<type 'unicode'>
Applying ``@python_2_unicode_compatible`` to a subclass
shouldn't break methods that was not overridden::
>>> baz.__repr__().__class__
<type 'str'>
>>> baz.unicode_repr().__class__
<type 'unicode'>
unicode_repr
------------
Under Python 3.x ``repr(unicode_string)`` doesn't have a leading "u" letter.
``nltk.compat.unicode_repr`` function may be used instead of ``repr`` and
``"%r" % obj`` to make the output more consistent under Python 2.x and 3.x::
>>> from nltk.compat import unicode_repr
>>> print(repr(u"test"))
u'test'
>>> print(unicode_repr(u"test"))
'test'
It may be also used to get an original unescaped repr (as unicode)
of objects which class was fixed by ``@python_2_unicode_compatible``
decorator::
>>> @python_2_unicode_compatible
... class Foo(object):
... def __repr__(self):
... return u'<Foo: foo>'
>>> foo = Foo()
>>> repr(foo)
'<Foo: foo>'
>>> unicode_repr(foo)
u'<Foo: foo>'
For other objects it returns the same value as ``repr``::
>>> unicode_repr(5)
'5'
It may be a good idea to use ``unicode_repr`` instead of ``%r``
string formatting specifier inside ``__repr__`` or ``__str__``
methods of classes fixed by ``@python_2_unicode_compatible``
to make the output consistent between Python 2.x and 3.x.