0

我有这样一个类结构:

list --(parent)--> ClipList --(parent)--> VolumeList

ClipList 只能存储 Clip 对象,而 VolumeList - 只能存储 Volume 对象。这有效(即从 ClipList 继承的方法适用于 VolumeList),因为 Volume 类继承自 Clip 类。因此,我尝试使用 Volume 和 VolumeList 类实现的目的是让 Clip 和 ClipList 的风格与原来的不同,从而拥有自己的类。

当我尝试从 VolumeList 调用 Volume 对象时,就会出现问题。为了找到一个被调用的剪辑的位置,我运行了一个二分搜索(因为列表是有序的)。搜索是一个简单的二进制搜索,并且脱离了上下文可以工作,所以我认为不值得在这里发布代码。有问题的一点是这个条件:

if ( self == [] ):
        return None

现在,二分查找是在ClipList类中实现的,并且由 VolumeList 继承。上述条件在使用 ClipList 时没有引起任何问题,但是当使用(已填充的)VolumeList 运行时,条件

self == []

是,由于某种原因,实际上True。因此,二分查找总是返回 None,并且我无法通过名称(它们的排序)访问列表中的任何 Volume 对象,它们只能通过索引访问。

现在,填充的 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