8

Im creating a simple python program that gives basic functionality of an SMS_Inbox. I have created an SMS_Inbox method.

store = []
message_count = 0
class sms_store:
    def add_new_arrival(self,number,time,text):
        store.append(("From: "+number, "Recieved: "+time,"Msg: "+text))
        **message_count += 1**
    def delete(self,i):
        if i > len(store-1):
            print("Index does not exist")
        else:
            del store[i]
            message_count -= 1

In the bolded bit I am getting an error:

UnboundLocalError: local variable 'message_count' referenced before assignment.

I created a global variable store which is an empty list and this works when I use the add_new_variable object. However for some reason it is not adding values to my global message_count variable.

Please help

7
  • 2
    None of your variables are called count... Commented Apr 25, 2013 at 8:48
  • Did you mean message_count? Commented Apr 25, 2013 at 8:49
  • Meant to quote: UnboundLocalError: local variable 'message_count' referenced before assignment Commented Apr 25, 2013 at 8:50
  • Its simple. In each function that you are using message_count, just add global message_count as the first statement. Needless to say, this approach on the whole should not be used at all. Use a class variable if you absolutely must. Commented Apr 25, 2013 at 9:01
  • 1
    Have to ask, why do you have message_count, when you can just do len(store)? Commented Apr 25, 2013 at 9:01

3 Answers 3

12

That's not how classes work. Data should be stored within the class instance, not globally.

class SMSStore(object):
    def __init__(self):
        self.store = []
        self.message_count = 0

    def add_new_arrival(self,number,time,text):
        self.store.append(("From: "+number, "Recieved: "+time,"Msg: "+text))
        self.message_count += 1

    def delete(self, i):
        if i >= len(store):
            raise IndexError
        else:
            del self.store[i]
            self.message_count -= 1

sms_store = SMSStore()
sms_store.add_new_arrival("1234", "now", "lorem ipsum")
try:
    sms_store.delete(20)
except IndexError:
    print("Index does not exist")

print sms_store.store

# multiple separate stores
sms_store2 = SMSStore()
sms_store2.add_new_arrival("4321", "then", "lorem ipsum")
print sms_store2.store
Sign up to request clarification or add additional context in comments.

5 Comments

If it is in the class instance, will it maintain the list items?
@eric the instance of self.store and self.message_count is not recording / saving values like i wanted and aimed for. Its just recording the instances of a add_new_arrival and not recording it in a list for further editing and adding.. such as a global variable would. So would I have to go with the global variable approach by creating the store list and message count outside the class and refer to it as a global variable in the class instance?
@user2318861: I have absolutely no idea what you're trying to say.
@eric you created the store (list) and the message_count under the init. Im trying to say that this will only work for recording ONE instance. It will not work on ACCUMULATING different instances such like a GLOBAL VARIABLE would. Ie. I want to be able to add MORE numbers to the list and the list will maintain all elements. I want to be able to use the list to store many numbers, not just an instance of numbers. Ive tested the method you stated by creating an instance of list and count under init but it keeps resetting the values if i call add_new_arrival after a previous add_new_arrival
Then only create one store.
9

If the variable you are referring to is message_count, the error is because in Python, you have to specify a variable as global before you can make edits with it.

This should work.

store = []
message_count = 0
class sms_store:
    def add_new_arrival(self,number,time,text):
        global message_count
        store.append(("From: "+number, "Recieved: "+time,"Msg: "+text))
        message_count += 1
    def delete(self,i):
        if i > len(store-1):
            print("Index does not exist")
        else:
            global message_count
            del store[i]
            message_count -= 1

As written above, you'd be better off encapsulating it in the __init__ function instead of declaring it global.

Comments

1

You are trying to assign to a global variable message_count without declaring it as such:

message_count = 0

class sms_store:
    def add_new_arrival(self,number,time,text):
        store.append(("From: "+number, "Recieved: "+time,"Msg: "+text))
        global message_count
        message_count += 1

Try to avoid using globals, or at least encapsulate the variable as a class attribute:

class sms_store:
    message_count = 0
    store = []

    def add_new_arrival(self,number,time,text):
        sms_store.append(("From: "+number, "Recieved: "+time,"Msg: "+text))
        sms_store.message_count += 1

However, your class instances have no state anymore, so there is no point in creating a class here. It only serves to confuse your purpose.

Either store state in instances, or use global functions (so don't use a class at all); the former is preferable to the latter.

Transforming your setup to a class whose instances hold state, using proper PEP-8 styleguide naming and string formatting:

class SMSStore(object):
    def __init__(self):
        self.store = []
        self.message_count = 0

    def add_new_arrival(self, number, time, text):
        self.store.append('From: {}, Received: {}, Msg: {}'.format(number, time, text))
        self.message_count += 1

You are then free to create one instance and use that as a global if needs be:

sms_store = SMSStore()

Other code just uses sms_store.add_new_arrival(...), but the state is encapsulated in one instance.

5 Comments

...and don't ever do that.
@Eric: Yeah, the OP probably didn't want to use global state at all, or should not use a class.
I did want to use global state. Why? I want to keep a record of all messages in the inbox. Hence I adjust message_count accordingly dependant on object calls to add_new_arrival or delete.
Thanks alot. Im going to be using the init attribute. Im hoping that it will MAINTAIN the entries into the self.store AND self.message_count so it will not reset on each execution of an instance of the class.
@user2318861: expanded to use one instance as global state.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.