Доступ к пользовательским атрибутам из Cython - PullRequest
0 голосов
/ 01 марта 2019

В каком-то месте моего кода мне нужно знать, какому количеству предложений принадлежит токен, поэтому я назначаю пользовательский атрибут следующим образом:

from spacy.tokens import Token
Token.set_extension('number', default=0)

После этого я хочу использоватьбыстрые циклы по токенам с Cython и доступ к этому атрибуту на уровне C ++.Я знаю, что у нас есть:

Token.get_struct_attr

, но, похоже, он не работает следующим образом:

def traverse_doc(Doc doc):
    cdef int n_tokens = len(doc)
    cdef tokens = []
    cdef attr_hash = doc.vocab.strings.add('number')
    for token in doc.c[:n_tokens]: 
        tokens.append(Token.get_struct_attr(&token, attr_hash))

Этот код создает следующий кортеж для каждого токена:

(0, None, None, None)

0 представляется значением атрибута по умолчанию, но при этом не учитывается значение, которое я назначаю этому атрибуту.

Как правильно обращаться к настраиваемым атрибутам?

1 Ответ

0 голосов
/ 06 марта 2019

Token.get_struct_attr по умолчанию 0, если атрибут не найден (или, точнее, он делегирует Lexeme.get_struct_attr, по умолчанию 0 - см. Здесь ).Тот факт, что значение расширения по умолчанию равно 0, является лишь слегка запутанным совпадением.Пользовательские атрибуты расширений, определенные пользователем, не сохраняются как данные C, поскольку они могут быть что угодно и, следовательно, не могут быть напечатаны.

Так что вместо doc.c вам нужнопроверить Python doc по указанному индексу токена:

for i in range(n_tokens):
   # Option 1: Use the ._ attribute
   number = doc[i]._.number
   # Option 2: Use the .get method with string attribute
   number = doc[i]._.get('number')
...