实例方法不是从对象开始工作,而是从它的类中工作

Ham*_*bad -1 python nlp python-3.x

这是我几年前开始使用Python编程以来最奇怪的错误.

首先,这些是我的课程(抱歉长代码):

class Quran(Iterable):

    def __init__(self):
        self.sourats = []

    def __iadd__(self, other):
        # There is some code here
        pass

    def __getitem__(self, sourat_num):
        if not (isinstance(sourat_num, int) or isinstance(sourat_num, slice)):
            raise TypeError('Indexing Quran can be done only using ints or slices')
        if isinstance(sourat_num, int):
            sourat_num -= 1
        else:
            sourat_num = slice(sourat_num.start - 1, sourat_num.stop)
        try:
            return self.sourats[sourat_num]
        except IndexError:
            return None

    def __len__(self):
        return len(self.sourats)

    # Other methods ...

class Sourat(Iterable):

    sourats_titles = [ # 114 strs here
    ]

    def __init__(self, number, quran):
        if not isinstance(number, int):
            raise TypeError('number must be int')
        if not isinstance(quran, Quran):
            raise TypeError('quran must be Quran')
        self.num = number
        self.ayats = []
        self.quran = quran

    def __int__(self):
        return self.num

    def __iadd__(self, other):
        # Some code here
        pass

    def __getitem__(self, ayat_num):
        if not (isinstance(ayat_num, int) or isinstance(ayat_num, slice)):
            raise TypeError('Indexing Sourat can be done only using ints or slices')
        if isinstance(ayat_num, int):
            ayat_num -= 1
        else:
            ayat_num = slice(ayat_num.start-1, ayat_num.stop)
        try:
            return self.ayats[ayat_num]
        except IndexError:
            return None

    def __len__(self):
        return len(self.ayats)

    def location(self):
        return self.num

    def previous(self):
        p_num = self.num-1
        if p_num < 1:
            return None
        return self.quran[p_num]

    def next(self):
        n_num = self.num+1
        if n_num > len(self.quran):
            return None
        return self.quran[n_num]

    # Other methods ...

class Word(Iterable):

    def __init__(self, number, text, features, ayat):
        if not isinstance(number, int):
            raise TypeError('number must be int')
        if not isinstance(text, str):
            raise TypeError('text must be str')
        if not (isinstance(features, dict) and features['type'] in ('PREFIX', 'STEM', 'SUFFIX')):
            raise TypeError('features[type] must be one of PREFIX, STEM, SUFFIX')
        if not isinstance(ayat, Ayat):
            raise TypeError('ayat must be Ayat')
        self.num = number
        self.text = text
        self.root = features.get('ROOT', None)
        self.lem = features.get('LEM', None)
        self.type = features['type']
        self.next = None
        self.previous = None
        self.ayat = ayat

    def __iadd__(self, other):
        # Some code here

    def __hash__(self):
        # Some code here
        pass

    def previous(self):
        p_num = self.num-1
        if p_num < 1:
            previous_ayat = self.ayat.previous()
            if previous_ayat:
                return previous_ayat[-1]
            else:
                return None
        return self.ayat[p_num]

    def next(self):
        n_num = self.num+1
        if n_num > len(self.ayat):
            next_ayat = self.ayat.next()
            if next_ayat:
                return next_ayat[0]
            else:
                return None
        return self.ayat[n_num]

        # Other methods ...
Run Code Online (Sandbox Code Playgroud)

这就是我在主代码中所拥有的:

quran_last_14_sourats = parse_quranic_corpus('quranic-corpus-morphology-0.4-last-14-sourats.txt')
sourat = quran_last_14_sourats[2]
ayat = sourat[2]
word = ayat[1]
assert isinstance(ayat, Ayat)
assert isinstance(word, Word)
print(ayat.previous())
print(ayat)
print(ayat.next())
print(Word.next(word))  # This works !!!
print(word.next())  # This doesn't work !!!
Run Code Online (Sandbox Code Playgroud)

我的问题是在next(self)previous(self)班上Word,一切完美的作品.

当我尝试使用word.next()或者word.previous(),它抱怨NoneType is not callable.我试图print(word.next)并且它显示None,但这不合逻辑,因为这两个方法都在类中Word.这个问题不会在类中发生Sourat,Ayat甚至它们具有相同的结构.而最疯狂的事情就是Word.next(word)没有任何问题!

这是Python 3中的错误吗?(顺便说一句,我使用的是最新版本:3.5.2)

Rob*_*obᵩ 5

这是Python 3中的错误吗?

总之,没有.

实例成员和实例方法共享相同的命名空间.因此,您的行Word.__init__():

self.next = None
Run Code Online (Sandbox Code Playgroud)

删除对Word.next()新分配Word对象内部方法的引用.

  • 不需要宽恕.你问了一个合理的问题; 这里的每个人都乐于回答这些问题.只记得投票和接受.但是,将来请阅读[mcve]并在发布问题之前应用这些技巧.我怀疑如果你将代码提炼到最小的完整示例,你会发现自己的错误. (3认同)