2016-10-19 2 views
-1

У меня есть класс под названием Maps, из которого я создал два списка l и lm. l должен изменяться с определенными событиями, но lm (список памяти) должен оставаться как есть.Python - Есть ли способ предотвратить изменение класса списка?

Есть ли способ предотвратить изменение класса списка? Тнак ты!

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") 
+5

Что вы подразумеваете под словом "предотвратить изменение"? Вещи не меняются сами по себе, что-то должно его изменять. Код, который вы опубликовали, недостаточно, чтобы выяснить, что происходит или что вы хотите; попробуйте создать [mcve]. – tzaman

+1

Существует действительно простой способ «запретить (ваш) класс списка изменять»: не меняйте его. Если это не отвечает на ваш вопрос, вы можете переформулировать свой вопрос с более подробными сведениями и примерами использования. –

+0

Также: наследование (наследование реализации - но это единственная причина использования наследования в Python) - это в основном очень искалеченная форма композиции/делегирования. Я настоятельно рекомендую вам переписать свой класс «Карты», используя композицию/делегацию. Сначала это немного больше, но это дает вам полный контроль над реализацией и большую гибкость. –

ответ

3

Вы могли бы хотеть, чтобы определить такие вещи, используя различные классы. Это не очень хорошая идея, когда экземпляры одного и того же класса изменяются и неизменяемы в одно и то же время.

Поэтому я предлагаю вам определить все методы в MixinClass, а затем сделать 2 класса, один подкласс list (изменяемый) другой является подкласс tuple (неизменный)

+2

Насколько я могу судить, я бы не наследовал ни тот, ни другой - состав/делегация работали лучше для меня в 99,9 раза из 100 за последние 17 лет. –

+0

Я буду читать больше документации о составе и делегировании. Спасибо! – Chihab

1

Может быть что-то вроде этого

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 
+0

'NotImplemented' - это имя встроенного объекта, поэтому я бы не рекомендовал использовать это имя для другой цели (даже если оно содержится в пространстве имен классов). Кроме того, если вы переопределяете все методы интерфейса списка, нет причин наследовать от 'list'. – Blckknght

+0

Я думал, потому что я работаю со списками. Но я сразу прочитаю об этом и посмотрю, что я могу изменить, чтобы сделать его лучше. – Chihab

Смежные вопросы