python - 在 nltk 中扩展一个类。 - Python

标签 python class inheritance nltk wordnet

目的是为nltk中的wordnet类添加额外的功能,例如:

from nltk.corpus import wordnet

class WN(wordnet):
    def foobar(self):
        print 'foobar'

x = WN
WN.foobar()

但它给出了一个错误:

Traceback (most recent call last):
  File "/home/alvas/workspace/pybabel-fresh/babelnet/utils/pybabel_WordNet.py", line 5, in <module>
    class WN(wordnet):
  File "/usr/local/lib/python2.7/dist-packages/nltk/corpus/util.py", line 44, in __init__
    assert issubclass(reader_cls, CorpusReader)
TypeError: Error when calling the metaclass bases
    issubclass() arg 1 must be a class

所以我尝试使用 nltk.corpus.reader.WordNetCorpusReader ( http://www.nltk.org/_modules/nltk/corpus/reader/wordnet.html#WordNetCorpusReader ):

from nltk.corpus.reader import WordNetCorpusReader

class WN(WordNetCorpusReader):
    def __init__(self):
        self = WN.__init__()

    def foobar(self):
        return "foobar"

x = WN
x.foobar()

如果我正在使用 WordNetCorpusReader,我仍然需要实例化它,所以我得到了:

Traceback (most recent call last):
  File "/home/alvas/workspace/pybabel-fresh/babelnet/utils/pybabel_WordNet.py", line 13, in <module>
    x.foobar()
TypeError: unbound method foobar() must be called with WN instance as first argument (got nothing instead)

然后我尝试了:

from nltk.corpus.reader import WordNetCorpusReader

class WN(WordNetCorpusReader):
    def foobar(self):
        return "foobar"

x = WN
for i in x.all_synsets():
    print i

[输出]:

Traceback (most recent call last):
  File "/home/alvas/workspace/pybabel-fresh/babelnet/utils/pybabel_WordNet.py", line 10, in <module>
    for i in x.all_synsets():
TypeError: unbound method all_synsets() must be called with WN instance as first argument (got nothing instead)

如何使用新函数扩展 nltk wordnet API?注意:目标是创建一个具有新函数的新类。

最佳答案

您的第二次尝试似乎最接近。您的构造函数存在问题:

class WN(WordNetCorpusReader):
    def __init__(self):
        self = WN.__init__()  # needs an instance as the first argument, recursive, and no need to assign to self

__init__ 方法需要一个实例作为它的第一个参数(这里是 self),此外你还调用了 __init__ 方法错误的类。这将导致 RuntimeError: maximum recursion depth exceeded 错误。最后,您只想调用该方法;您不需要将方法的结果分配给 self

我认为你打算改为这样做:

from nltk.corpus.reader import WordNetCorpusReader
import nltk

class WN(WordNetCorpusReader):
    def __init__(self, *args):
        WordNetCorpusReader.__init__(self, *args)

    def foobar(self):
        return "foobar"

但要注意的是,您需要将所需的 WordNetCorpusReader.__init__ args 传递给您的新类。在我的 nltk 版本中,这意味着您需要传递一个 root 参数,如下所示:

>>> x = WN(nltk.data.find('corpora/wordnet'))
>>> x.foobar()
'foobar'
>>> x.synsets('run')
[Synset('run.n.01'), Synset('test.n.05'), ...]

更高效的方法

做同样事情的一种更有效的方法如下:

class WN(WordNetCorpusReader):
    root = nltk.data.find('corpora/wordnet')  # make root a class variable, so you only need to load it once
    def __init__(self, *args, **kwargs):
        WordNetCorpusReader.__init__(self, WN.root, *args, **kwargs)  # add root yourself here, so no arguments are required

    def foobar(self):
        return "foobar"

现在测试一下:

>>> x = WN()
>>> x.foobar()
'foobar'
>>> x.synsets('run')
[Synset('run.n.01'), Synset('test.n.05'), ...]

顺便说一句,我很高兴看到你在 nltk 标签上的工作。

关于python - 在 nltk 中扩展一个类。 - Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27203429/

相关文章:

python - matplotlib - 允许条形图超出图表限制吗?

python - 如何添加功能 "see other computer on this local network"?

python - 在 Django View 中检索 Select2 多值以在后端使用

c++ - 分配给类中函数指针的函数

java - 继承和私有(private)方法

c++ - 从 std::vector 中的每个对象调用重载函数

python - 如何为实例更改 dict() 的行为

c++ - 如何在C++中初始化一个类?

java - 使用基类实例化派生类有什么好处? java

c++ - 以基类作为数据成员的派生类?