104

Suppose I have this code:

class Example(object): def the_example(self): itsProblem = "problem" theExample = Example() print(theExample.itsProblem) 

When I try it, I get an error that says:

Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Example' object has no attribute 'itsProblem' 

How do I access this attribute? I tried adding another method to return it:

 def return_itsProblem(self): return itsProblem 

but the problem persists.

0

5 Answers 5

184

The answer, in a few words

In your example, itsProblem is a local variable.

Your must use self to set and get instance variables. You can set it in the __init__ method. Then your code would be:

class Example(object): def __init__(self): self.itsProblem = "problem" theExample = Example() print(theExample.itsProblem) 

But if you want a true class variable, then use the class name directly:

class Example(object): itsProblem = "problem" theExample = Example() print(theExample.itsProblem) print (Example.itsProblem) 

But be careful with this one, as theExample.itsProblem is automatically set to be equal to Example.itsProblem, but is not the same variable at all and can be changed independently.

Some explanations

In Python, variables can be created dynamically. Therefore, you can do the following:

class Example(object): pass Example.itsProblem = "problem" e = Example() e.itsSecondProblem = "problem" print Example.itsProblem == e.itsSecondProblem 

prints

True

Therefore, that's exactly what you do with the previous examples.

Indeed, in Python we use self as this, but it's a bit more than that. self is the the first argument to any object method because the first argument is always the object reference. This is automatic, whether you call it self or not.

Which means you can do:

class Example(object): def __init__(self): self.itsProblem = "problem" theExample = Example() print(theExample.itsProblem) 

or:

class Example(object): def __init__(my_super_self): my_super_self.itsProblem = "problem" theExample = Example() print(theExample.itsProblem) 

It's exactly the same. The first argument of ANY object method is the current object, we only call it self as a convention. And you add just a variable to this object, the same way you would do it from outside.

Now, about the class variables.

When you do:

class Example(object): itsProblem = "problem" theExample = Example() print(theExample.itsProblem) 

You'll notice we first set a class variable, then we access an object (instance) variable. We never set this object variable but it works, how is that possible?

Well, Python tries to get first the object variable, but if it can't find it, will give you the class variable. Warning: the class variable is shared among instances, and the object variable is not.

As a conclusion, never use class variables to set default values to object variables. Use __init__ for that.

Eventually, you will learn that Python classes are instances and therefore objects themselves, which gives new insight to understanding the above. Come back and read this again later, once you realize that.

Sign up to request clarification or add additional context in comments.

4 Comments

you say: "theExample.itsProblem is automatically set to be equal to Example.itsProblem, but is not the same variable at all and can be changed independently" - but that is not quite right, and your phrase is misleading. I trust you know what is going on there, so I's suggest rephrasing that: "it is the same variable, but it can be rebinded independently for each object".
Yes, but binding is a concept somebody for an other programming language such as Java or C (as I suspect the OP is) that is completly unknown. Then I would I to explain what binding is, then late binding, then the problem with references on mutable objects. It would be too long. I think sometime you must sacrifice precision on the altar of understanding.
There is also (I think this may be 2.7+) the @classmethod decorator, worth looking into. interesting discussion here - stackoverflow.com/questions/12179271/…
name-binding: I think it is a bad idea to give false statements, no matter what level. I suggest this slight edit: But be careful with this one, as theExample.itsProblem is automatically set to be equal to Example.itsProblem, but, from practical perspective*, is not the same variable at all and can be changed independently. *: actually it starts out as the same object but it is very easy to accidentally change that if you don't understand Python's name-binding
14

You are declaring a local variable, not a class variable. To set an instance variable (attribute), use

class Example(object): def the_example(self): self.itsProblem = "problem" # <-- remember the 'self.' theExample = Example() theExample.the_example() print(theExample.itsProblem) 

To set a class variable (a.k.a. static member), use

class Example(object): def the_example(self): Example.itsProblem = "problem" # or, type(self).itsProblem = "problem" # depending what you want to do when the class is derived. 

1 Comment

Except that class variables are declared once at class-level. Your way will reset it upon every instanciation, this really isn't what you want. Also see stackoverflow.com/questions/2709821/python-self-explained for the rationale behind explicit self.
10

If you have an instance function (i.e. one that gets passed self) you can use self to get a reference to the class using self.__class__

For example in the code below tornado creates an instance to handle get requests, but we can get hold of the get_handler class and use it to hold a riak client so we do not need to create one for every request.

import tornado.web import riak class get_handler(tornado.web.requestHandler): riak_client = None def post(self): cls = self.__class__ if cls.riak_client is None: cls.riak_client = riak.RiakClient(pb_port=8087, protocol='pbc') # Additional code to send response to the request ... 

3 Comments

This is a very good example to demonstrate the question from the OPs original title. Actually the OPs example does not match the titel and other answers refer to the example. Anyway, this is the best way to access a class level variable because it does not violate the DRY principle. Like some of the other examples do. It is better to use self.__class__ instead of repeating the class name. It makes the code future proof, makes refactoring easyer and if you dare to use subclassing this can also have advantages.
Readers should be warned that the use of a handler like above can lead to problems not only in non singlethreaded applications. Mutiple instances of the class could in theory use the same handler iin parallel, and if the handler is not designed to do this, which depends on its internal structure, it might not work. 'In parallel' in a single threaded application means, the first class instance has not finished using the handler and then a second instance starts using the handler. In such cases it could be advised to use an instance variable instead.
cls = self.__class__ was exactly what I needed.
1

If you have a @classmethod static method, you always have the class as the first parameter:

class Example(object): itsProblem = "problem" @classmethod def printProblem(cls): print(cls.itsProblem) Example.printProblem() 

Comments

0

Implement the return statement like the example below! You should be good. I hope it helps someone..

class Example(object): def the_example(self): itsProblem = "problem" return itsProblem theExample = Example() print theExample.the_example() 

1 Comment

You should fix your code indentation. There are also superior answers to this question and your answer is a basic variation on those answers, not an alternate solution...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.