首页 > 解决方案 > 如何将对象从主模块传递到另一个模块

问题描述

以下代码运行没有错误

import spacy
from spacy.matcher import PhraseMatcher
nlp = spacy.load('en_core_web_lg')

test = nlp(' FWCA rate of pay')

phrase_pattern = [r'Rate of Pay']
pattern_name = 'RATES'
patterns = [nlp.make_doc(name) for name in phrase_pattern]

matcher = PhraseMatcher(nlp.vocab, attr='LOWER')
matcher.add(pattern_name, None, *patterns)

matches = matcher(test)
for match_id, start, end in matches:
    matched_span = test[start:end]
    print(matched_span.text)     
    print('- ', matched_span.sent.text)

# Returned:
rate of pay
-   FWCA rate of pay

然后我将部分代码移动到一个单独的模块中,以便我可以在另一个项目中使用它

# my_module.py

def find_matches(pattern_name, phrase_pattern, doc, attr="LOWER"):
    import spacy
    from spacy.matcher import PhraseMatcher
    nlp = spacy.load('en_core_web_lg')

    patterns = [nlp.make_doc(name) for name in phrase_pattern]
    matcher = PhraseMatcher(nlp.vocab, attr='LOWER')
    matcher.add(pattern_name, None, *patterns)

    matches = matcher(doc)
    for match_id, start, end in matches:
        matched_span = doc[start:end]
        print(matched_span.text)     
        print('- ', matched_span.sent.text)

但是当我运行这段代码时,我得到了一个错误

import spacy
from spacy.matcher import PhraseMatcher
from my_module import find_matches

nlp1 = spacy.load('en_core_web_lg')
test = nlp1(' FWCA rate of pay')

find_matches(pattern_name, phrase_pattern, test, attr="LOWER")

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-63-1bc18aa51d61> in <module>()
     10 matcher.add(pattern_name, None, *patterns)
     11 
---> 12 matches = matcher(test)
     13 for match_id, start, end in matches:
     14     matched_span = test[start:end]

phrasematcher.pyx in spacy.matcher.phrasematcher.PhraseMatcher.__call__()

phrasematcher.pyx in spacy.matcher.phrasematcher.PhraseMatcher.get_lex_value()

strings.pyx in spacy.strings.StringStore.__getitem__()

KeyError: "[E018] Can't retrieve string for hash '12488114723688465754'."

错误的原因是nlp函数内部的对象与 main 中的对象find_matches不同。nlp1

我的问题是:

  1. 如何将nlp1对象传递给函数find_matches,即我不会nlp = spacy.load('en_core_web_lg')在函数内部声明?那可能吗?

  2. 如果函数不能继承nlp1对象,我该如何克服这个问题?

我的想法是我应该将原始文本作为函数的参数传递,然后doc像这样在其中创建一个对象

find_matches(pattern_name, phrase_pattern, text, attr="LOWER"):
    doc = nlp(text)
    ....
    ....

那效率高吗?

标签: pythonspacy

解决方案


回答您的问题:

1)如何将nlp1对象传递给函数find_matches,即我不会在函数内部声明nlp = spacy.load('en_core_web_lg')?那可能吗?

您可以将 nlp 作为属性传递,因为它是一个对象。当您执行 spacy.load() 时,您正在构建一个管道对象,其中包含您作为参数传递的嵌入、配置和机器学习模型(例如“en_core_web_lg”)。

2) 如果函数不能包含 nlp1 对象,我该如何解决这个问题?

如上所述,您可以将对象作为参数传递。但是,为什么这会是一个问题?事实上,如果您正在为部署做一些产品,我建议您将 nlp 设置为在初始化时实例化的类变量。

除非您使用不同的管道,否则没有理由多次加载 spacy,尤其是考虑到这是一个缓慢的过程(它从磁盘读取)。

最后:

find_matches(pattern_name, phrase_pattern, text, attr="LOWER"):
    doc = nlp(text)
    ....
    ....

那效率高吗?

是的,这是一种非常有效的方法。当您制作 doc = nlp(text) 时,您正在使用此 nlp 全局对象来生成管道处理的结果,该结果对每个文本都是单独的,因为它带有文本标签、跨度等。

-- 在作者自己的解决方案后补充 --

另一个有效的解决方案是将“doc”对象作为引用传递,尤其是在函数式编程风格中它将被几个不同的函数使用时。此 doc 对象包含来自已处理文本的所有相关结果。


推荐阅读