0

私はそのようなクラス構造を持っています:

list --(親)--> ClipList --(親)--> VolumeList

ClipList は Clip オブジェクトのみを格納でき、VolumeList は Volume オブジェクトのみを格納できます。Volume クラスは Clip クラスから継承されるため、これは機能します (つまり、ClipList から継承されたメソッドは VolumeList に対して機能します)。そこで、Volume クラスと VolumeList クラスで達成しようとしているのは、オリジナルとは十分に異なる、独自のクラスを持つことができる、Clip と ClipList のフレーバーを得ることです。

VolumeList から Volume オブジェクトを呼び出そうとすると、問題が発生します。呼び出されたクリップの場所を見つけるために、バイナリ検索を実行します (リストの順序に従って)。検索は単純な二分検索であり、文脈を無視しても機能するため、ここにコードを掲載する価値はないと思います。問題のあるビットは、次の条件です。

if ( self == [] ):
        return None

現在、バイナリ検索はClipListクラスに実装されており、VolumeList によってのみ継承されます。上記の条件は、ClipList を使用する場合には問題を引き起こしませんでしたが、(既に入力された) VolumeList を使用して実行すると、条件

self == []

は、何らかの理由で、実際にはTrue. したがって、二分検索は常に None を返し、リスト内のボリューム オブジェクトに名前 (順序付け) でアクセスすることはできません。インデックスによってのみアクセスできます。

これで、入力された VolumeList は次のようになります (ただし、はるかに大きくなります)。

[<__main__.Volume instance at 0xb6f3b1ac>, <__main__.Volume instance at 0xb6f3b24c>]

また、ClipList が VolumeList とは別のモジュールにあるという事実も言及する価値があります。これには役割があるかもしれませんが、私にはわかりません。

必要に応じてさらにコードを投稿することもできますが、問題 (および解決策) は上記の部分にあると感じています。上記のビットとは別にテストした場合、他のコードは機能するようです。

問題はどこにある可能性がありますか? 状態はなぜTrueですか?

コードは次のとおりです。

  1. ClipList.findIndex:

    def findIndex(self, clip, start = 0, end = None, pos = 0):
    
        # Finds the index of the place where the given clip should be added.
        # It does that by looking at the *tapes* of the clips, and finds
        # a place where the *tape* of the clip could be inserted without
        # distorting the order. It then looks at clip's timecode to put it
        # in the right place according to the timecode. The 'pos' parameter
        # carries the information about the index which we will return.
    
        # Define the right end place if none is specified
        if ( end == None ):
            end = len(self) - 1
    
        # But first of all, check if there is a need to find the place of the
        # clip - i. e. if the list isn't empty.
        if ( not self ):
            return None
    
        # The second check that we have to make - whether it isn't the case
        # that we have already found what we need, i. e. the closest element
        # in the list to the clip we search.
        if ( start > end ):
            return pos
    
        # Now, we can implement the actual search. To do that,
        # we use the binary search algorithm.
        middle = (start + end) / 2
        currTape = Clip.physicalTape( self[middle].VOLUME )
        goalTape = Clip.physicalTape( clip.VOLUME )
    
        if ( currTape > goalTape ):
            return self.findIndex(clip, start, middle -1, middle )
    
        if ( currTape < goalTape ):
            return self.findIndex(clip, middle + 1, end, middle + 1)
    
        if ( currTape == goalTape ):
    
            currTimecode = self[middle].IN
            goalTimecode = clip.IN
    
            if ( currTimecode > goalTimecode ):
                return self.findIndex(clip, start, middle - 1, middle )
    
            if ( currTimecode < goalTimecode ):
                return self.findIndex(clip, middle + 1, end, middle + 1)
    
  2. VolumeList.__getitem__:

    def __getitem__(self, key):
        # Is called whenever someone tries to get an item of the list
        # by calling 'volumes[ some_text_or_number ]'. VolumeList
        # will act as a normal list in all occassions except where the
        # key is a string. There, it will search for a volume label or
        # a tape number.
    
        if ( isinstance( key, basestring ) ):
    
            # Before checking whether the argument is a volume 
            # number, try to find if the user hasn't made an inquiry
            # about a tape. Tapes can only be called by calls such as
            # 'volumes[ "HD00345" ]', and *not* any other calls.
            if ( len(key) == 7 and key[:2].upper() == 'HD' 
                               and key[2:].isdigit() ):
    
                # Try to find the start and end of the sequence of 
                # volumes from the tape. To do this, search for an
                # 'infinitely small' and 'infinitely big' volumes from
                # the tape.
                start = self.findIndex( Volume( key.upper() + 'A', inFrame = -1 ) )
                end   = self.findIndex( Volume( key.upper() + 'Z', inFrame = 9999999 ) )
    
                if ( start != None and end != None ):
                    return self[start:end]
                else:
                    raise KeyError( 'The tape is not represented in this VolumeList!' )
    
            # Otherwise, assume that the user has called a particular
            # volume.
            volume = Volume.volumeLabel( key )
    
            if ( volume != None ):
                index = self.findIndex( Volume( volume, inFrame = -1 ) )
    
                if ( index < len( self ) and index != None ):
    
                    if ( self[ index ].LABEL == volume ):
                        return list.__getitem__(self, index)
                    else:
                        print 'The volume is here but not exactly'
                        raise KeyError( 'The volume is not in the list!' )
                else:
                    raise KeyError( 'The volume is not in the list!' )
            else:
                raise KeyError( 'Tried to call a volume by an invalid volume label!' )
    
        else:
            return list.__getitem__(self, key)
    
4

0 に答える 0