两个班级之间共享资源

问题描述 投票:2回答:1

我提供了一个工作实例,在这个实例中,我有一个在Python 3中作为自定义类型实现的动态数组。我希望使用这个动态数组的单个实例作为一个通用资源来实现,比如说。N 堆栈。我怎么做呢?

我想,我想让每个堆栈只访问特定部分的 DynamicArray 划清界线 _start_end. 为了有 _start_end 对于每一个堆栈,我想把它们包在一个帮助类中。_StackRecord. 如果我成功地提供了一个可修改的观点,那么,我就可以在此基础上进行修改。DynamicArray我想 _StackRecord 来完成所有的弹出和推送的重任,使堆栈不发生碰撞,而底层的人却能得到更好的服务。DynamicArray 根据需要扩大缩小。我知道我的要求太高了,但我可能会在做不到这一点的时候学到一些无用的技能。

任何对模块化、可维护性和良好实践的建议批评都是全心全意的欢迎。

import ctypes

class DynamicArray:
    """Expandable array class similar to Python list"""
    def __init__(self, size=0):
        self._n        = size
        self._capacity = size + 1
        self._A        = self._make_low_level_array(self._capacity)
        
    def _make_low_level_array(self, capacity):
        return (capacity*ctypes.py_object)()
    
    # following two methods are needed for Python to implement __iter__
    def __len__(self):
        return self._n
    
    def __getitem__(self, index_key):
        if isinstance(index_key, slice):
            start, stop, step = index_key.indices(len(self))
            return [self._A[i] for i in range(start, stop, step)]
        elif isinstance(index_key, int):
            if 0 <= index_key < self._n :
                return self._A[index_key]
            else:
                raise IndexError("index out of bounds")
        elif isinstance(index_key, tuple):
            raise NotImplementedError('Tuple as index')
        else:
            raise TypeError('Invalid argument type: {}'.format(type(key)))
         
    def __setitem__(self, index_k, value):
        if 0 <= index_k < self._n :
            self._A[index_k] = value
        else:
            raise IndexError("index out of bounds")
    ###################################################################        
    
class FixedMultiStack:
    class _StackRecord(DynamicArray):
        def __init__(self, array: DynamicArray, stack_number=0, size_of_each=10):
            self._stack = stack_number
            self._start = stack_number*size_of_each
            self._end   = self._start + size_of_each
            # try commenting the following lines
            self._n     = size_of_each
            self._A     = DynamicArray(self._n)
            # If I have to use self._A then I would like it to point 
            # to array[self._start:self._end]
            for i in range(self._start, self._end):
                array[i]   = i
            for i in range(self._n):
                self._A[i] = array[self._start+ i]

    def __init__(self, numStack=1, sizeEach=10):
        self._stacks = []
        self._items  = DynamicArray(numStack*sizeEach)
        
        for i in range(numStack):
            self._stacks.append(self._StackRecord(self._items, i, sizeEach))
            
    def __getitem__(self, stack_number):
        return self._stacks[stack_number]
    
if __name__ == "__main__":
    fms = FixedMultiStack(3,10)
    print(list(fms[0]))
    print(list(fms[1]))
    print(list(fms[2]))
    print(list(fms._items))

课题

我在做浪费的行为,做了一个叫做地方副本的行为。self._A. 我如何避免这种情况?为什么我不能在传递给本地记录保存者的全局动态数组上工作呢?_StackRecord?

我期待的是什么?

  1. fms = FixedMultiStack(3,10), 一个固定的多堆栈包装3个堆栈,每个堆栈大小为10,这样

  2. 我想,如果 self._A 必要时,当地 self._A 指该部分 DynamicArray 对应于给定的栈号。

  3. 所以 print(list(fms[n])) 给我第n个栈的内容

  4. print(list(fms._items)) 应该给我所有堆栈的联合状态。Yikes! print(list(fms._items)) 是丑陋的。怎么样 print(list(fms))?

  5. 我应该可以写出这样的内容 self._items[n].push(val), self._items[n].pop() 来推送和弹出第n个栈。

python python-3.x
1个回答
2
投票

你可以使用 memoryview 用于在整个数组上创建不同的视图。

class FixedMultiStack:
    def __init__(self, m, n):
        self.data = bytearray(m*n)
        view = memoryview(self.data)
        self.stacks = [view[i*n:(i+1)*n] for i in range(m)]

    def __getitem__(self, index):
        return self.stacks[index]
© www.soinside.com 2019 - 2024. All rights reserved.