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

2024-10-02 22:31:31 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我多年前开始用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)previous(self)Word中,其他一切都很好地工作

当我尝试使用word.next()word.previous()时,它会抱怨NoneType is not callable。我试着print(word.next),它显示了None,但这不符合逻辑,因为这两个方法在类Word中。这个问题不会发生在类SouratAyat中,即使它们具有相同的结构。最疯狂的是Word.next(word)毫无问题地工作

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


Tags: selfnonereturnifdefnotnumnext