2016-11-21 9 views
-1

これは何年も前に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)でありますクラスWordprevious(self)は、他のすべてが完全に機能します。

word.next()またはword.previous()を使用しようとすると、NoneType is not callableという文句があります。私はprint(word.next)を試しましたが、Noneと表示されましたが、これらの2つのメソッドがクラスWordの内部にあるため、これは論理的ではありません。この問題は、同じ構造であっても、クラスSouratAyatでは発生しません。そして最も狂ったことは、Word.next(word)が問題なく動作することです!

これはPython 3のバグですか? (私は最新バージョン3.5.2を使用しています)

答えて

5

これはPython 3のバグですか?

インスタンスメンバーとインスタンスメソッドは同じ名前空間を共有します。したがって、Word.__init__()のあなたのライン:

self.next = None 

は、新しく割り当てられたWordオブジェクト内のメソッドWord.next()への参照を抹消します。

+0

私の無知を許して、私はちょうど感謝した! –

+3

赦免は必要ありません。あなたは正当な質問をしました。誰もがここに答えてうれしいです。投票して受け入れてください。しかし、将来は質問を投稿する前に[mcve]を読んでそれらのテクニックを適用してください。私はあなたのコードを蒸留して最小限の完全な例にしていれば、あなた自身のエラーを見つけたと思う。 –

関連する問題