python - 将自定义生成器添加到 spaCy 的类
问题描述
我很难将生成器添加到 spaCy 的Token
课程中。
首先,一个通用的 Python 相当于我正在尝试做的事情,它按预期工作。
class Foo:
def __init__(self, n):
self.n = n
@property
def lower_int_generator(self):
x = 0
while x < self.n:
yield x
x += 1
Foo.lower_ints = lower_int_generator
a = Foo(5)
print(type(a.lower_ints)) # <class 'generator'>
[x for x in a.lower_ints] # [0, 1, 2, 3, 4]
现在在 spaCy 中,它提供了一个set_extension
方法(参见文档)。
@property
def letter_generator(self):
for x in self.text:
yield x
spacy.tokens.token.Token.set_extension('letters', default=letter_generator, force=True)
doc = nlp('Hello world')
print(type(doc[0]._.letters)) # <class 'property'>
[x for x in doc[0]._.letters] # TypeError: 'property' object is not iterable
值得注意的是,spaCy@property
在它自己的代码中使用,它工作得很好。这里有什么问题?
解决方案
好吧,default
属性是既没有也没有设置时返回的值,因此这就是返回的值getter
(setter
如果删除property
装饰器,则为属性或函数)。您可以通过这种方式存储一些静态信息。
您想像getter
在回答中所做的那样进行设置,因为这是您想要获取属性值时调用的操作。setter
更改值时必须创建,如下所示:
doc[0]._.letters = "A"
setter
提供除 之外的其他值会很好default
,尽管到目前为止我还没有使用过这种方法。
最后,我找到了一种干净的扩展方式spacy
(并且 IMO 比所提供的更具可读性),lemmatization
扩展示例:
class Lemmatizer:
def __init__(self):
self.lemmatizer = spacy.lemmatizer.Lemmatizer(
spacy.lang.en.LEMMA_INDEX,
spacy.lang.en.LEMMA_EXC,
spacy.lang.en.LEMMA_RULES,
)
def __call__(self, token):
corrected = token._.text
if token.text == corrected:
return token.lemma_
return self.lemmatizer(corrected, token.pos_)[0]
spacy.tokens.Token.set_extension("lemma", getter=Lemmatizer(), force=True)
如您所见,唯一需要使用的是__call__
重载方法(不需要生成器,但您也可以使用它,具体取决于您的任务上下文)。
推荐阅读
- php - 在 apache 服务器上读取 GPS 轨迹
- node.js - 猫鼬查找与执行。如何返回值?
- javascript - 在javascript中以等于或大于它的数字拆分字符串
- asp.net-mvc - 使用 javascript 渲染 FileContentResult
- python - 将所有选定的值替换为熊猫中的 NaN
- c++ - 如何在模板化函数中使用内置类型映射用户定义的枚举?
- excel - 在 Excel 中创建自定义函数(预览版)
- wordpress - 使用 wp_enqueue_scripts 将 css 和 js 链接到我的主题的 Wordpress 不起作用
- xamarin.forms - 评估平台
- android - 防止用户返回上一个屏幕 StackNavigator