Counter variable for class

Go To StackoverFlow.com

15

I am having problem getting this piece of code to run. The class is Student which has a IdCounter, and it is where the problem seems to be. (at line 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)

I am trying to have this idCounter inside my Student class, so I can have it as part of the student's name (which is really an ID#, for example Student 12345. But I have been getting error.

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

I tried to put the idCounter += 1 in before, after, all combination, but I am still getting the referenced before assignment error, can you explain to me what I am doing wrong?

2012-04-04 05:22
by George
Have you looked at the line immediately following - Ignacio Vazquez-Abrams 2012-04-04 05:28
Why I haven't thought about that... (Orginally my code wrote Student.idCounter = 0 - George 2012-04-04 05:32
Aside from the particular error, increments are not atomic in Python so the naive counter may cause race conditions. The better way would be to use itertools.count - bereal 2012-04-04 06:13
posted a follow up question to your question using your example herehussam 2018-02-09 05:52


27

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)

Thanks to the point out by Ignacio, Vazquez-Abrams, figured it out...

2012-04-04 05:31
by George
Also, take note that your first comment is grossly inaccurate - Ignacio Vazquez-Abrams 2012-04-04 05:32
Yea, actually it is just a counter and nothing else. (Dont really know what to comment on it, maybe should just remove the comment all together). Thank you very much Ignacio Vazquez-Abrams - George 2012-04-04 05:34


1

Coming to this answer some time ago helped me find what I needed to sort out class versus instance variables and their scoping. So, an extension, which does the same thing, only using a generator. The generator assigns a unique number to the student as idCounter does -- only it consumes the values. There is no prev method on the generator class, of which I'm aware. Neither idGenerator nor idCounter is memoized, so if you want to externalize the list then come back to add one or more students, you'd have to update the range(start,,) accordingly, or iterate through each value without assigning it until you arrive at the unique one in sequence, a path somewhat shorter with idCounter which you cou simply set with a single dummy instance construct and go.

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)
2018-07-12 22:59
by Tim Pozza
Ads