Чтобы было ясно, я предположил, что вопрос заключается в том, почему входные данные для объекта Tree
в NLTK являются целыми числами, но при печати представление выводит строку без каких-либо ошибок.
Давайте немного углубимся в код.
Часть, которая печатает Tree
в читаемом человеком формате анализа в скобках, - это функция __str__()
при https://github.com/nltk/nltk/blob/develop/nltk/tree.py#L820
Если мы посмотрим поближе, то вызовет функцию pformat()
:
def __str__(self):
return self.pformat()
Функция pformat()
при https://github.com/nltk/nltk/blob/develop/nltk/tree.py#L835:
def pformat(self, margin=70, indent=0, nodesep='', parens='()', quotes=False):
"""
:return: A pretty-printed string representation of this tree.
:rtype: str
:param margin: The right margin at which to do line-wrapping.
:type margin: int
:param indent: The indentation level at which printing
begins. This number is used to decide how far to indent
subsequent lines.
:type indent: int
:param nodesep: A string that is used to separate the node
from the children. E.g., the default value ``':'`` gives
trees like ``(S: (NP: I) (VP: (V: saw) (NP: it)))``.
"""
# Try writing it on one line.
s = self._pformat_flat(nodesep, parens, quotes)
if len(s) + indent < margin:
return s
# If it doesn't fit on one line, then write it on multi-lines.
if isinstance(self._label, string_types):
s = '%s%s%s' % (parens[0], self._label, nodesep)
else:
s = '%s%s%s' % (parens[0], unicode_repr(self._label), nodesep)
for child in self:
if isinstance(child, Tree):
s += (
'\n'
+ ' ' * (indent + 2)
+ child.pformat(margin, indent + 2, nodesep, parens, quotes)
)
elif isinstance(child, tuple):
s += '\n' + ' ' * (indent + 2) + "/".join(child)
elif isinstance(child, string_types) and not quotes:
s += '\n' + ' ' * (indent + 2) + '%s' % child
else:
s += '\n' + ' ' * (indent + 2) + unicode_repr(child)
return s + parens[1]
Если мы посмотрим, как создается переменная string s
в функции pformat
, мы увидим многократное использование unicode_repr()
.
Вот где входные данные преобразуются в строку внутри pformat при печати, но дочерний элемент и значения в объекте Tree
по-прежнему остаются того же типа, что и при вводе.
Теперь, если мы посмотрим на unicode_repr
в nltk.tree.py
,
from nltk.compat import python_2_unicode_compatible, unicode_repr
Мы видим, что оно исходит от nltk.compat
с https://github.com/nltk/nltk/blob/develop/nltk/compat.py#L298
def unicode_repr(obj):
"""
For classes that was fixed with @python_2_unicode_compatible
``unicode_repr`` returns ``obj.unicode_repr()``; for unicode strings
the result is returned without "u" letter (to make output the
same under Python 2.x and Python 3.x); for other variables
it is the same as ``repr``.
"""
if PY3:
return repr(obj)
# Python 2.x
if hasattr(obj, 'unicode_repr'):
return obj.unicode_repr()
if isinstance(obj, text_type):
return repr(obj)[1:] # strip "u" letter from output
return repr(obj)
В Python 3 nltk.compat.unicode_repr
просто возвращает repr
, который по умолчанию в Юникоде, в частности utf8
IIRC.
Но в Python 2 он сначала проверяет, есть ли у объекта функция unicode_repr()
monkey-patch.
Затем он проверяет, что это тип text_type
из библиотеки six
, если это так, он распечатает вывод без префикса u
, например. u"..."
Наконец, это Python 2, и объект не имеет unicode_repr()
и не six.text_type
, он просто распечатает repr(obj)
.
Итак, возвращаясь к вопросу, в случае, когда объект является целым числом, repr(int)
будет преобразован в строку.
>>> type(1)
<class 'int'>
>>> repr(1)
'1'
>>> type(repr(1))
<class 'str'>