【问题标题】:Python - Is there a way to prevent my list class from changing? [closed]Python - 有没有办法防止我的列表类发生变化? [关闭]
【发布时间】:2023-03-16 06:50:01
【问题描述】:

我有一个名为Maps 的类,我从中创建了两个列表llml 应该随着某些事件而改变,但 lm(内存列表)应该保持原样。

有没有办法防止我的列表类发生变化? 认识你!

class Maps(list):

    def createInitial(self, lvlC):
        #self.extend(mapDico[lvlC.value])

    #get (i,j) coords of "i" in l
    def findI(self):
        for ordinate, abscissa in enumerate(self):
            try:
                return (ordinate, abscissa.index("i"))
            except:
                pass

    #get number of "x" in lm
    def countX(self):
        nbX=0
        for rows in range(len(self)):
            for elements in range(len(self)):
                if self[rows][elements]=="x":
                    nbX+=1
        return nbX

    #load next map
    def nextLevel(self, nxtL):
        del self[:]
        self.extend(mapDico[nxtL])

lvlC=Counters()
lm=Maps()
lm.createInitial(lvlC)
l=Maps()
l.createInitial(lvlC)

这里开始“控制器”文件:

             if goalC.value>0 and goalC.value==lm.countX():
            lvlC.increment(1)
            #lvl.config(text=" | Level Complete ", bg="limegreen")
            l.nextLevel(lvlC.value)
            lm.nextLevel(lvlC.value)
            muvC.reinitialize()
            nbMuv.config(text="Moves: "+str(muvC.value))
            pushC.reinitialize()
            nbPush.config(text=" | Pushes: "+str(pushC.value))
            goalC.reinitialize()
            nbGoal.config(text=" | Goals: "+str(goalC.value))
            lvl.config(text=" | Current level: "+str(lvlC.value), bg="darkgray")
            print("New moves",muvC.value, "New pushes",pushC.value, "New level",lvlC.value)
            print("New countX: ", lm.countX())
            print("New goals: ", goalC.value)
            for i in l:
                print(i)
            for i in lm:
                print(i)
            can.delete("all")
            for i in r:
                for j in r:
                    time.sleep(.005)
                    can.create_rectangle(j*n, i*n, j*n+n, i*n+n, fill=fillSquare(i,j, l), outline="darkslategray")

【问题讨论】:

  • “防止改变”是什么意思?事情不会自己改变,一定有什么东西在改变它。您发布的代码不足以弄清楚发生了什么或您想要什么;请尝试创建一个minimal reproducible example
  • 确实有一种非常简单的方法可以“防止(你的)列表类改变”:不要改变它。如果这不能回答您的问题,您可能需要用更具体的细节和用例重新表述您的问题。
  • 另外:继承(实现继承——但这是在 Python 中使用继承的唯一原因)主要是一种非常残缺的组合/委托形式。我强烈建议你改用组合/委托重写你的Maps 类。一开始需要做更多的工作,但它可以让您完全控制实施并提供更大的灵活性。
  • 请注意,Maps() + [] 将返回 []。所以要拥有一个合适的子类,你必须重新实现很多方法。
  • 好吧,我正在开发一款我制作事件的游戏,他们会修改l 列表。我只希望该列表响应事件。但即使我没有给出更改lm 的指示,它也确实发生了变化。我会加入我的整个代码,但它会占用页面。 ^^>

标签: python list class oop


【解决方案1】:

您可能希望使用不同的类来定义这些东西。让同一个类的实例同时可变和不可变并不是一个好主意。

所以我建议你在 MixinClass 中定义所有方法,然后创建 2 个类,一个是 list(mutable) 的子类,另一个是 tuple(immutable) 的子类

【讨论】:

  • 就我而言,我不会从其中一个继承或另一个继承 - 在过去 17 年中,组合/委派在 100 次中对我来说有 99.9 次效果更好。
  • 我会阅读更多关于组合和委托的文档。谢谢!
【解决方案2】:

也许是这样的

class BaseMaps(list):

def createInitial(self, lvlC):
    #self.extend(mapDico[lvlC.value])

#get (i,j) coords of "i" in l
def findI(self):
    for ordinate, abscissa in enumerate(self):
        try:
            return (ordinate, abscissa.index("i"))
        except:
            pass

#get number of "x" in lm
def countX(self):
    nbX=0
    for rows in range(len(self)):
        for elements in range(len(self)):
            if self[rows][elements]=="x":
                nbX+=1
    return nbX

#load next map
def nextLevel(self, nxtL):
    del self[:]
    self.extend(mapDico[nxtL])



class Maps(BaseMaps):

    pass


class ReadOnlyMaps(BaseMaps):
    def __init__(self, other):
        self._list = other

    def __getitem__(self, index):
        return self._list[index]

    def __iter__(self):
        return iter(self._list)

    def __slice__(self, *args, **kw):
        return self._list.__slice__(*args, **kw)

    def __repr__(self):
        return repr(self._list)

    def __len__(self):
        return len(self._list)

    def NotImplemented(self, *args, **kw):
        raise ValueError("Read Only list proxy")

    append = pop = __setitem__ = __setslice__ = __delitem__ = NotImplemented

【讨论】:

  • NotImplemented 是内置对象的名称,因此我不建议将该名称用于其他目的(即使它包含在类命名空间中)。此外,如果您要覆盖所有列表接口方法,则没有理由从 list 继承。
  • 我认为是因为我正在处理列表。但我会立即阅读更多相关信息,看看我可以做出哪些改变以使其变得更好。
猜你喜欢
  • 1970-01-01
  • 2010-09-28
  • 2019-05-27
  • 2020-10-10
  • 2015-11-11
  • 2010-11-17
  • 1970-01-01
  • 1970-01-01
  • 2011-09-24
相关资源
最近更新 更多