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

时间:2016-11-21 20:27:37

标签: python python-3.x nlp

这是我几年前开始使用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 ...

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

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 !!!

我的问题出在班级next(self)的{​​{1}}和previous(self),其他一切都运作正常。

当我尝试使用Wordword.next()时,它会抱怨word.previous()。我尝试NoneType is not callable并显示print(word.next),但这不符合逻辑,因为这两个方法都在类None中。类WordSourat中不会发生此问题,即使它们具有相同的结构。最疯狂的是Ayat没有任何问题!

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

1 个答案:

答案 0 :(得分:5)

  

这是Python 3中的错误吗?

总之,没有。

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

self.next = None

在新分配的Word.next()对象中删除对方法Word的引用。