在外部库的命名空间中创建一个 Python 模块(自定义 spaCy 语言)
Creating a Python module in the namespace of an external library (custom spaCy language)
这个问题是在 spaCy v2 library 添加语言的上下文中,但它可能是一个通用的 python 包装问题。
在 spaCy 中,语言是 Language
基础 class 的子class,并且大部分工具都希望将给定的语言放置在规范命名的包中(例如spacy.lang.en
英文)。
有多种方法可以满足此要求(例如,@spacy.registry.languages
),但这通常需要一些权衡(例如,您必须先导入一些代码来注册您的 classes,然后一切都很好,但是当您拥有自定义脚本、prodigy
食谱、库等工具时,这些工具不允许您“注入”自定义导入或有自己的方式这样做,这是行不通的 -或者通常容易出错)。如果有办法的话,我很乐意听到有关缓解此问题的建议。
所以我想我只要把我的语言放在 spaCy 期望的地方,就可以了。创建语言 subclass 是 documented enough.
所以我引导了一个库:
lib/
src/
spacy/
lang/
ka/ # example of a language that spaCy does not know about
__init.py__ # my language subclass
setup.py
init.py是一种简单的语言(简体):
import spacy
from spacy.language import Language
class GeorgianDefaults(Language.Defaults):
@spacy.registry.languages("ka")
class Georgian(Language):
lang = "ka"
Defaults = GeorgianDefaults
而我的 setup.py 是标准的,使用本地命名空间包:
setup(
name="my-spacy-extras",
packages=find_namespace_packages(where="src"),
package_dir={"": "src"},
install_requires=[
"spacy>=2.3.0,<3.0.0"
]
)
我考虑过使用本机命名空间包,因为据我所知,这是针对此用例的现代方式。
但是当我打包代码时(或者实际上只是设置了一个 virtualenv 和 pip install -Ur requirements.txt
并且要求很简单 -e .
),我得到了可怕的
ModuleNotFoundError: No module named 'spacy.lang.ka'
我认为这是因为 spaCy 本身(参见 repo)不使用本地命名空间打包,但它既不使用 pkgutil 样式的包,我开始怀疑这是否可行。
那么,我是否有办法将我的自定义语言创建为一个模块,将其打包到一个库中,在 spacy 命名空间内(找不到更好的词)?
请务必遵循 spaCy v2 的 v2 文档,因为存在许多差异。 (注册表装饰器是 v3 中的新增功能)。
spaCy v2 支持自定义语言的入口点:https://v2.spacy.io/usage/saving-loading#entry-points
您的包将有自己的名称(不是 spacy
),您可以通过在 setup.py
中的 spacy_languages
下添加入口点来在 spaCy v2 中添加自定义语言:
entry_points={
"spacy_languages": [
"ka = spacy_lang_ka:Georgian",
]
}
如果您的环境中安装了此软件包,那么 spacy.blank("ka")
应该可以找到并将此 class 加载为 Georgian()
,而无需任何额外的步骤。同样,prodigy 应该能够将空白语言管道加载为 blank:ka
.
在 spacy-stanza
v0.2.5:
中显示了完整 setup.py
中的示例
https://github.com/explosion/spacy-stanza/blob/v0.2.5/setup.py
这个问题是在 spaCy v2 library 添加语言的上下文中,但它可能是一个通用的 python 包装问题。
在 spaCy 中,语言是 Language
基础 class 的子class,并且大部分工具都希望将给定的语言放置在规范命名的包中(例如spacy.lang.en
英文)。
有多种方法可以满足此要求(例如,@spacy.registry.languages
),但这通常需要一些权衡(例如,您必须先导入一些代码来注册您的 classes,然后一切都很好,但是当您拥有自定义脚本、prodigy
食谱、库等工具时,这些工具不允许您“注入”自定义导入或有自己的方式这样做,这是行不通的 -或者通常容易出错)。如果有办法的话,我很乐意听到有关缓解此问题的建议。
所以我想我只要把我的语言放在 spaCy 期望的地方,就可以了。创建语言 subclass 是 documented enough.
所以我引导了一个库:
lib/
src/
spacy/
lang/
ka/ # example of a language that spaCy does not know about
__init.py__ # my language subclass
setup.py
init.py是一种简单的语言(简体):
import spacy
from spacy.language import Language
class GeorgianDefaults(Language.Defaults):
@spacy.registry.languages("ka")
class Georgian(Language):
lang = "ka"
Defaults = GeorgianDefaults
而我的 setup.py 是标准的,使用本地命名空间包:
setup(
name="my-spacy-extras",
packages=find_namespace_packages(where="src"),
package_dir={"": "src"},
install_requires=[
"spacy>=2.3.0,<3.0.0"
]
)
我考虑过使用本机命名空间包,因为据我所知,这是针对此用例的现代方式。
但是当我打包代码时(或者实际上只是设置了一个 virtualenv 和 pip install -Ur requirements.txt
并且要求很简单 -e .
),我得到了可怕的
ModuleNotFoundError: No module named 'spacy.lang.ka'
我认为这是因为 spaCy 本身(参见 repo)不使用本地命名空间打包,但它既不使用 pkgutil 样式的包,我开始怀疑这是否可行。
那么,我是否有办法将我的自定义语言创建为一个模块,将其打包到一个库中,在 spacy 命名空间内(找不到更好的词)?
请务必遵循 spaCy v2 的 v2 文档,因为存在许多差异。 (注册表装饰器是 v3 中的新增功能)。
spaCy v2 支持自定义语言的入口点:https://v2.spacy.io/usage/saving-loading#entry-points
您的包将有自己的名称(不是 spacy
),您可以通过在 setup.py
中的 spacy_languages
下添加入口点来在 spaCy v2 中添加自定义语言:
entry_points={
"spacy_languages": [
"ka = spacy_lang_ka:Georgian",
]
}
如果您的环境中安装了此软件包,那么 spacy.blank("ka")
应该可以找到并将此 class 加载为 Georgian()
,而无需任何额外的步骤。同样,prodigy 应该能够将空白语言管道加载为 blank:ka
.
在 spacy-stanza
v0.2.5:
setup.py
中的示例
https://github.com/explosion/spacy-stanza/blob/v0.2.5/setup.py