Список в классе продолжает исчезать - PullRequest
0 голосов
/ 10 января 2020

Я учу Python, в основном через проект MIT OpenCourseWare. Я пытаюсь выполнить задачу 2 задания 9 здесь .

. В ней есть оболочка кода, в которой просто есть заголовки классов и определений с комментариями. Я добавил действительный код ниже

class ShapeSet:
    def __init__(self):
        """
        Initialize any needed variables
        """
        self.set1=[]
        set1=self.set1

    def addShape(self, sh):
        """
        Add shape sh to the set; no two shapes in the set may be
        identical
        sh: shape to be added
        """
        self.set1=[]
        set1=self.set1
        a=True
        for x in set1:
            if x==sh:
                a=False
        if a:
            set1.append(sh)
        return set1
        print(set1[:])

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

  1. В IDLE я говорю s=ShapeSet(), чтобы создать экземпляр. Я должен делать это каждый раз, потому что в противном случае он исчезает, и я получаю NameError, что 's' is not defined. Почему оно не сохраняется?

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

  3. Вы видите, что я определил там set1 дважды. Если я просто введу его в __init__, как я и предполагал, я получу ошибку, что set1 не определено. Почему это будет неопределенным, если он находится в init? В связи с этим меня всегда смущало, как вещи называются в классах. Почему люди всегда переименовывают x=self.x? Можно ли просто назвать его set1 для начала и избегать self.set1?

Ответы [ 2 ]

1 голос
/ 10 января 2020

Нет необходимости делать set1 = self.set1, просто используйте self.set1.

Когда вы запускаете s = ShapeSet(), вы инициализируете класс, который во время этого запускает код под def __init__(self):, вы устанавливаете self.set1 = [], пустой список.

Это была бы прекрасная возможность для вас прочитать self и __init__ в классе. Есть большой вопрос StackOverflow, охватывающий это;

__init__ и self

Python Конструкторы

Ваш код работает нормально, пока вы измените все ваши звонки на set1 на self.set1 и инициализируйте класс только один раз.

class ShapeSet:
    def __init__(self):
        """
        Initialize any needed variables
        """
        self.set1=[]

    def addShape(self, sh):
        """
        Add shape sh to the set; no two shapes in the set may be
        identical
        sh: shape to be added
        """

        a=True
        for x in self.set1:
            if x==sh:
                a=False
        if a:
            self.set1.append(sh)
        return self.set1
        print(self.set1[:])

>>> s = ShapeSet()
>>> s.addShape('Square')
['Square']
>>> s.addShape('Circle')
['Square', 'Circle']
>>> s.addShape('Square')
['Square', 'Circle']
0 голосов
/ 10 января 2020
  1. Каждый раз, когда вы нажимаете run в IDLE, все переменные очищаются, так что ваша программа каждый раз работает одинаково и запускается в чистом сеансе.

  2. Первые две строки вашей addShape функции, похоже, были скопированы по ошибке из __init__, и они сбрасывают список как пустой.

  3. Когда вы объявляете несколько функций, они не не имеют доступа к переменным, определенным в других функциях. Обе эти функции имеют доступ к self, поскольку они передаются в качестве аргумента. Но когда вы объявляете set1 = self.set1, вы создаете локальную переменную, которая уничтожается при возврате функции. Вы можете прочитать больше о переменной scope здесь

...