What happens when you initialize instance variables outside of __init__

In python, when you initialize an instance variable (for example self.my_var

), you must do it in your class function __init__

so that memory is properly allocated for that variable per instance ( <- my error, see below ). When you want to define class-level variables, you do so outside the function and without a prefix self

.

What happens when you create a variable inside a non __init__

-prefixed function self

? It behaves like a normal instance variable, is there a good reason not to? other than the danger of making the logic of the code implicit, which is enough already, but I'm wondering if you are potentially dealing with memory or other hidden problems if you do?

I couldn't find what was discussed somewhere.

Update sorry

I've misinterpreted some of the answers including the first and third here Python __init__ and myself, what do they do? (looking for others) and thought it __init__

was a special type of function, believing it somehow had memory allocation functionality (!?). Wrong question.

+3


source to share


4 answers


The method is __init__

not special. The only thing that makes it __init__

interesting is the fact that it gets called when you call MyClass()

.

The following equivalents:

# Set inside __init__
class MyClassA:
    def __init__(self):
        self.x = 0
obj = MyClassA()

# Set inside other method
class MyClassB:
    def my_initialize(self):
        self.x = 0
obj = MyClassB()
obj.my_initialize()

# Set from outside any method, no self
class MyClassC:
    pass
obj = MyClassC()
obj.x = 0

      

Which does an instance variable when you assign it, and it can happen anywhere. Also note that it self

is not special either, it is just a normal function parameter (and in fact you can call it something other than self

).



so that memory is reserved for this variable per instance.

You don't need to "reserve memory" in Python. With regular object instances, when you assign self.x = 0

or obj.x = 0

, it's like moving a value into a dictionary. Actually,

# This is sometimes equivalent, depending on how obj is defined
obj.__dict__['x'] = 0

      

+4


source


It has nothing to do with "reserving memory". Python is not C; you should absolutely not think about memory allocation when writing Python.

As a dynamic language, Python behaves exactly the same wherever you set an attribute, and __init__

is in no way privileged when it comes to creating attributes.



The main reason for this is because then it gives your class a consistent interface. Unless you assign at least a placeholder on instantiation, any code that accesses this attribute should check to see if it even exists initially.

However, there are still many use cases where dynamic attribute annotation is useful and perfectly acceptable.

+2


source


__init__

is a kind of constructor for python classes when you define a variable with self, for example self.abc

it becomes an attribute of an object that can be accessed using self or object. It is initialized during the very creation of the object.

When you define a variable outside __init__

or any functions inside a class without self

, it becomes a static attribute for that class. and remains the same for all instances for that class.

If you define it within other member functions of class c self

, it is very similar to what you do in __init__

, it just isn't called automatically when you instantiate it, but you must explicitly call it

0


source


I was looking for an answer for this Question as I defined a global variable with myself inside a method instead of a method __init__

and it didn't affect my code. But when I needed to use this variable in another method - before calling the method that initiated the variable, it didn't work. Obviously the variable hasn't been defined yet! So the answer would be that we are defining all global variables in the method __init__

because it is run after instantiation from your class. This way, defining all the variables from the start and using them whenever you want in any approaching method.
initializing a global variable with a normal method will force you to execute that method before using that variable in any other way.

0


source







All Articles