Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why accessing to class variable from within the class needs "self." in Python? [duplicate]

Possible Duplicate:
Python ‘self’ explained

I'm learning Python and I have a question, more theoretical than practical, regarding access class variables from method of this class.

For example we have:

class ExampleClass:
    x = 123
    def example_method(self):
        print(self.x)

Why is necessarily to write exactly self.x, not just x? x belongs to namespace of the class, and method using it belongs to it too. What am I missing? What a rationale stands behind such style?

In C++ you can write:

class ExampleClass {
public:
    int x;
    void example_method()
    {
        x = 123;
        cout << x;
    };
};

And it will work!

like image 482
Gill Bates Avatar asked Nov 30 '12 19:11

Gill Bates


People also ask

Why do Python class methods need self?

self represents the instance of the class. By using the “self” we can access the attributes and methods of the class in python. It binds the attributes with the given arguments. The reason you need to use self. is because Python does not use the @ syntax to refer to instance attributes.

What is the purpose of self in Python?

The self parameter is a reference to the current instance of the class, and is used to access variables that belongs to the class.

How do you access class variables in Python?

The variables that are defined inside the class but outside the method can be accessed within the class(all methods included) using the instance of a class. For Example – self. var_name. If you want to use that variable even outside the class, you must declared that variable as a global.

What happens if you don't use self in Python?

If there was no self argument, the same class couldn't hold the information for both these objects. However, since the class is just a blueprint, self allows access to the attributes and methods of each object in python. This allows each object to have its own attributes and methods.


2 Answers

It seems to be related to module vs. class scope handling, in Python:

COLOR = 'blue'

class TellColor(object):
    COLOR = 'red'

    def tell(self):
        print self.COLOR   # references class variable
        print COLOR        # references module variable

a = TellColor()
a.tell()

> red
> blue
like image 56
heltonbiker Avatar answered Oct 12 '22 16:10

heltonbiker


Here's the content I did in an ancient answer concerning this feature:


The problem you encountered is due to this:

A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition.

(...)

A scope defines the visibility of a name within a block.

(...)

The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods – this includes generator expressions since they are implemented using a function scope. This means that the following will fail:

class A:

   a = 42  

   b = list(a + i for i in range(10))

http://docs.python.org/reference/executionmodel.html#naming-and-binding

The above means: a function body is a code block and a method is a function, then names defined out of the function body present in a class definition do not extend to the function body.


It appeared strange to me, when I was reading this, but that's how Python is crafted:

The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods

That's the official documentation that says this.

.

EDIT

heltonbiker wrote an interesting code:

COLOR = 'blue'

class TellColor(object):
    COLOR = 'red'

    def tell(self):
        print self.COLOR   # references class variable
        print COLOR        # references module variable

a = TellColor()
a.tell()

> red
> blue

It made me wonder how the instruction print COLOR written inside the method tell() provokes the printing of the value of the global object COLOR defined outside the class.
I found the answer in this part of the official documentation:

Methods may reference global names in the same way as ordinary functions. The global scope associated with a method is the module containing its definition. (A class is never used as a global scope.) While one rarely encounters a good reason for using global data in a method, there are many legitimate uses of the global scope: for one thing, functions and modules imported into the global scope can be used by methods, as well as functions and classes defined in it. Usually, the class containing the method is itself defined in this global scope (...)

http://docs.python.org/2/tutorial/classes.html#method-objects

When the interpreter has to execute print self.COLOR, as COLOR isn't an instance attribute (that is to say the identifier 'COLOR' doesn't belong to the namespace of the instance), the interpreter goes in the namespace of the class of the instance in search for the identifier 'COLOR' and find it, so it prints the value of TellColor.COLOR

When the interpreter has to execute print COLOR, as there is no attribute access written in this instruction, it will search for the identifier 'COLOR' in the global namespace, which the official documentation says it's the module's namespace.

like image 26
eyquem Avatar answered Oct 12 '22 15:10

eyquem