Home > Enterprise >  Basics about Python class
Basics about Python class

Time:08-24

I'm trying to learn about the basic construction of the python class. I have the following code which is completely running fine:

class Test1:
    name = 'Choton'
    age = 28

class Test2: # __init__ function executes whenever the class is called
    def __init__(self):
        self.name = 'Choton'
        self.age = 28
        print('Class Test2 is called and initialized...')

def main():
    # Test1
    print(f'Test1:')
    print(f'Test1().name = {Test1().name}, Test1().age = {Test1().age}')
    print(f'Test1.name = {Test1.name}, Test1.age = {Test1.age}\n')

    # Test2
    print(f'Test2:')
    print(f'Test2().name = {Test2().name}, Test2().age = {Test2().age}')
    # DOES NOT WORK
    # print(f' name = {Test2.name}, age = {Test2.age}')


if __name__ == '__main__':
    main()

I know that the __init__ function always runs whenever a class is initialized. Here the Test1 class do not have any __init__ function and both Test1.name and Test1().name works fine. But whenever I am calling the name using the __init__ function in Test2, the Test2.name does not work anymore. It says the following error if I uncomment that line: AttributeError: type object 'Test2' has no attribute 'name'.

What is the difference in here? Why both syntax work for one class and not for the other? I am a bit confused about it. Is there any syntactic sugar in here or any generalization that I am missing?

CodePudding user response:

In Test1 you are defining class variables, which are shared between all objects, and can be accessed by using the class only (Test1.name) as well as from the instance (Test1().name). Defining self.name in Test2.__init__ makes it an instance variable, which is only available on a specific instance of the class, e.g. new object created by Test2()

CodePudding user response:

Took me a long time to get my head around classes, I'm still not there. The init function isn't needed in every class, one thing it's used for is to allocate different values to the class attributes.

For info,

Test1 is the class.

Test1() is an instance of the class.

Both can be assigned. So you could say:

MyClassInstanceA = Test1()
MyClassInstanceB = Test1()

... These two are different items because they are both instances of the Test1 class, each instance is unique.

Or you could say

MyClassA = Test1
MyClassB = Test1

... These two are the same thing as they are both allocated Test1, not Test1()....

name and age are attributes. In the case of Test1 they are "class attributes". That is, the exist at the class level. They can be accessed via the class or an instance of the class. Remember Test1 is the class Test1() is an instance of the class.

The subtle difference between Test1() and Test1 is what is causing the error.

To further explain. In the Test1 class, the two attributes name and age exist in the class, before we create an instance of the class. If we do create any instances name and age attributes will be the same across all instances. But the important thing here is we don't have to create an instance of the class to access them. That's why Test1.name works....

On the other hand, in Test2 class. The attributes are only created when the class is initiated (this is what the init function is doing). They don't exist until then. So, when we want to access them you need to access them via an instance of the class Test2().name....

MyClassC = Test2

... Still no instance of the class so name or age doesn't exist

MyClassInstanceD = Test2()

... Now we have an instance of the class so name and age exists and it is accessed via that class which is called MyClassInstanceD...

MyClassInstanceD.name = 'Choton'

But as name and age only exist in the instance we can still not call

Test2.name

as this still doesn't exist and never will unless you modify the Test2 class...

  • Related