首页 > 解决方案 > 从 Cython 访问自定义属性

问题描述

在我的代码的某个地方,我需要知道令牌所属的句子数是多少,因此我分配了一个自定义属性,如下所示:

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 似乎是属性的默认值,但它不注意我分配给该属性的值。

访问自定义属性的正确方法是什么?

标签: cythonspacy

解决方案


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')

推荐阅读