17

Вопрос по class-variables, python – Счетчик переменной для класса

У меня проблемы с запуском этого куска кода. Класс Student, у которого есть IdCounter, и именно в этом проблема. (в строке 8)

class Student:
    idCounter = 0
    def __init__(self):
        self.gpa = 0
        self.record = {}
        # Each time I create a new student, the idCounter increment
        idCounter += 1
        self.name = 'Student {0}'.format(Student.idCounter)

classRoster = [] # List of students
for number in range(25):
    newStudent = Student()
    classRoster.append(newStudent)
    print(newStudent.name)

Я пытаюсь иметь этот idCounter внутри моегоStudent класс, так что я могу иметь его как часть имени студента (который на самом деле является ID #, например,Student 12345, Но я получаю ошибку.

Traceback (most recent call last):
  File "/Users/yanwchan/Documents/test.py", line 13, in <module>
    newStudent = Student()
  File "/Users/yanwchan/Documents/test.py", line 8, in __init__
    idCounter += 1
UnboundLocalError: local variable 'idCounter' referenced before assignment

Я пытался поместить idCounter + = 1 до, после, всей комбинации, но я все еще получаюreferenced before assignment ошибка, можете ли вы объяснить мне, что я делаю не так?

  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от George
  • Помимо конкретной ошибки, приращения не являются атомарными в Python, поэтому наивный счетчик может вызвать условия гонки. Лучше было бы использоватьitertools.count.

    от bereal
  • Почему я не подумал об этом ... (Обычно мой код писалStudent.idCounter = 0)

    от George
  • Вы смотрели на строку сразу после?

    от Ignacio Vazquez-Abrams
  • опубликовал дополнительный вопрос на ваш вопрос, используя ваш примерhere

    от hussam
  • 29

    Благодаря замечанию Игнасио, Васкес-Абрамс понял это ...

    class Student:
        # A student ID counter
        idCounter = 0
        def __init__(self):
            self.gpa = 0
            self.record = {}
            # Each time I create a new student, the idCounter increment
            Student.idCounter += 1
            self.name = 'Student {0}'.format(Student.idCounter)
    
    classRoster = [] # List of students
    for number in range(25):
        newStudent = Student()
        classRoster.append(newStudent)
        print(newStudent.name)
    

  • 1

    Приход к этому ответу некоторое время назад помог мне найти то

    что мне нужно, чтобы отсортировать переменные класса и экземпляра и их область видимости. Итак, расширение, которое делает то же самое, только используя генератор. Генератор присваивает студенту уникальный номер, как это делает idCounter - только он потребляет значения. Здесь нетprev метод класса генератора, о котором я знаю. Ни idGenerator, ни idCounter не запоминаются, поэтому, если вы хотите экстернализовать список, а затем вернуться, чтобы добавить одного или нескольких учащихся, вам необходимо соответствующим образом обновить диапазон (start ,,) или выполнить итерацию по каждому значению, не назначая его до получите уникальный в последовательности путь, несколько короче с помощью idCounter, который вы можете просто установить с помощью одной фиктивной конструкции экземпляра и идти.

    class Student:
        """ Implement a shared generator among all sub-classes
        in addition to idCounter. """
    
        # A student ID counter
        idCounter = 0
        # A student ID from generator
        idGenerator = (x for x in range(0xAAAAAA, 0xEEEEEE, 0xBA))
    
        def __init__(self):
            self.gpa = 0
            self.record = {}
            # Each time I create a new student, the idCounter increment
            Student.idCounter += 1
            self.id = Student.idGenerator.__next__()
            self.name = f"{self.id} Student {Student.idCounter}"
    
    classRoster = [] # List of students
    for number in range(25):
        newStudent = Student()
        classRoster.append(newStudent)
        print(newStudent.name)