User avatar
jadro
Posts: 395
Joined: Sun Oct 02, 2016 1:20 pm
Location: Croatia

Class questions

Thu Feb 07, 2019 9:24 pm

Hi,

I started to learn Python Class (OOP).

I have example code with commented question...
Can Anyone explained to me my questions in comment?
I do not understaind some pieces of class variables...

This is the code:

Code: Select all

#!/usr/bin/env python3

class A:
    def __init__(self):
       self.__num = 1
       print("1. Init num: ", self.__num)

    def setNum(self,value):
        self.__num = value

class B:
    def __init__(self, class_a):
        BA = class_a
        #print("class B is getting __num from class A: ",BA.__num) # This is not working, why???
        print("3. class B is getting __num from class A: ",BA._A__num) # Why this is 1? Why not 5? Is true that class B is inputing parameter instance of class A or not?
        # If BA._A__num is from A self.__num, what is BA.__num? How this is not same?
        BA.__num = 88
        print("4. New __num from class A: ",BA.__num)
        BA._A__num = 33
        print("5. New _A__num from class A: ",BA._A__num)

def main():
    a = A() # init num is printed
    a.__num = 5
    print("2. Print num: ",a.__num)
    b = B(a) # Init num from class B is called, it prints __num from class A
    print("6. Final __num form class A:",a.__num) # This I don't understaind!!! Why __num is not 88?
    print("7. Final __num as _A__num:",a._A__num) # If __num is not __num 88 from class B why this _A__num is 33 like in class B?
    a.setNum(45)
    print("8. Final __num after A.setNum procedure:",a.__num) # OMG, why __num is not initiated with 45?
    print("9. Final _A__num:",a._A__num) # instead of this one line up, this is initiated with 45, why this?

if __name__ == '__main__':
    main()
Thanx in advance,
Jadro
Oracle backend database developer
SmartHome IoT & Microprocessor enthusiast and hobbyist

User avatar
MrYsLab
Posts: 331
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Class questions

Thu Feb 07, 2019 10:21 pm

It is not clear why you are using name mangling (the variables with the leading double underscore). You are also trying to refer to the variables using the mangled name - again it is unclear what you are trying to do.

Usually, name mangling is used in conjunction with inheritance, but your example uses containment.

Here is an article about name mangling that may help: http://python.robasworld.com/private-me ... -mangling/

And StackOverflow discusses this here: https://stackoverflow.com/questions/116 ... -in-python

User avatar
jadro
Posts: 395
Joined: Sun Oct 02, 2016 1:20 pm
Location: Croatia

Re: Class questions

Thu Feb 07, 2019 10:38 pm

Hi,
thanx for the links.
I am new in OOP and I try to learn about private and public variables, instance and class variables and found nothing but close to this that I have written. Yes, maybe i am on the wrong way, i just want to learn. I will read from those links, thanx,
Jadro
Oracle backend database developer
SmartHome IoT & Microprocessor enthusiast and hobbyist

User avatar
MrYsLab
Posts: 331
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Class questions

Thu Feb 07, 2019 10:50 pm

Trying to learn is a good thing - keep asking questions. In some of my projects, I use inheritance and sometimes multiple levels of inheritance (a very rare occurrence), but have never found the need to perform name mangling. Maybe I just got lucky ;)

User avatar
jadro
Posts: 395
Joined: Sun Oct 02, 2016 1:20 pm
Location: Croatia

Re: Class questions

Fri Feb 08, 2019 6:42 am

I dont think it's luck, i think it's good practice. I rather follow a good and right direction. Thanx
Oracle backend database developer
SmartHome IoT & Microprocessor enthusiast and hobbyist

User avatar
MrYsLab
Posts: 331
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Class questions

Fri Feb 08, 2019 3:59 pm

Maybe not so much luck as having touched a hot stove enough times, I sometimes know when to avoid the next touch. ;-).

So, I still don't understand the application of using double underbar variables when using containment :

Code: Select all

class B:
    def __init__(self, class_a):

In this definition, class B contains an instance of class A that was instantiated before class B was instantiated.

Where things make more sense in my mind is the case of inheritance. In that case, one may want to protect a variable in the parent class. The way the double underbar variable works is that the mangled variable is only accessible within the class where it is defined.

Here is an example and then some output that I hope helps illustrated this for you:

Code: Select all

#!/usr/bin/env python3


class A:
    def __init__(self):
        self.__num = 1

    def set_num(self, value):
        self.__num = value

    def get_num(self):
        print('get_num from A: ', self.__num)


class B(A):
    def __init__(self):
        self.__num = 73
        super(B, self).__init__()

    def set_num(self, value):
        self.__num = value

    def get_num(self):
        print('get_num from B: ', self.__num)


def main():
    print('Step 1')
    b = B()
    b.get_num()
    print('Step 2')
    a = A()
    a.get_num()
    b.get_num()
    print('Step 3')
    a.__num = 5
    b.set_num(23)
    a.get_num()
    b.get_num()
    print('Step 4')
    a.set_num(4)
    a.get_num()
    b.get_num()
    print('Step 5')
    b.set_num(88)
    a.get_num()
    b.get_num()

if __name__ == '__main__':
    main()
And the output:

Code: Select all

Step 1
get_num from B:  73
Step 2
get_num from A:  1
get_num from B:  73
Step 3
get_num from A:  1
get_num from B:  23
Step 4
get_num from A:  4
get_num from B:  23
Step 5
get_num from A:  4
get_num from B:  88

User avatar
MrYsLab
Posts: 331
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Class questions

Fri Feb 08, 2019 4:04 pm

Just one more point. If you are coming from the OOP world of C++ or Java, OOP in Python is somewhat similar but there are differences. The underpinnings of Python sometimes provides unexpected results.

The lesson I have learned from Python, although the language does not enforce this in any way, is to keep things as simple as possible - this helps avoid hours of confusion - I am easily confused ;-).

User avatar
jadro
Posts: 395
Joined: Sun Oct 02, 2016 1:20 pm
Location: Croatia

Re: Class questions

Fri Feb 08, 2019 4:17 pm

Thanx. I learn OOP in Java..
This example will help yes, any piece of examples helps me to understaind more from OOP and Python.
My example is trying to change instance of class A with getting it through constructor in instance B..
Oracle backend database developer
SmartHome IoT & Microprocessor enthusiast and hobbyist

User avatar
jadro
Posts: 395
Joined: Sun Oct 02, 2016 1:20 pm
Location: Croatia

Re: Class questions

Mon Feb 11, 2019 4:49 pm

Code: Select all

class MyClass:
    glo_class = 11
    def method(self):
        """
        Instance methods need a class instance and
        can access the instance through `self`.
        """
        print("method1: "+str(self.glo_class))
        self.glo_class = 1
        print("method2: "+str(self.glo_class))
        print("method3: "+str(MyClass.glo_class))
        return 'instance method called', self
        
a = MyClass()
a.method()
Simple MyClass prints:
method1: 11
method2: 1
method3: 11

I thought that glo_class is not same as self.glo_class method1. How this is 11 in Method1?

self.glo_class = 1
this set up glo_class to 1 and print MyClass.glo_class is 11? wtf?
Oracle backend database developer
SmartHome IoT & Microprocessor enthusiast and hobbyist

User avatar
MrYsLab
Posts: 331
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Class questions

Mon Feb 11, 2019 5:30 pm

When you use self with the class variable, an instance variable with the same name as the class variable is created within the instance.
It is initially a local copy of the class variable. If you modify it, you are modifying the instance variable and not the class variable.

As you can see in you method3 line, the class variable was not changed. If you however did something like:

Code: Select all

MyClass.glo_class = 99
And then instantiated MyClass, glo_class would contain 99.

I hope this makes some sense.

User avatar
MrYsLab
Posts: 331
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Class questions

Mon Feb 11, 2019 5:32 pm

I modified your code somewhat to help illustrate this:

Code: Select all

class MyClass:
    glo_class = 11

    def method(self):
        """
        Instance methods need a class instance and
        can access the instance through `self`.
        """
        print("method1: " + str(self.glo_class))
        self.glo_class = 1
        print("method2: " + str(self.glo_class))
        print('using class name: ', MyClass.glo_class)
        print("method3: " + str(MyClass.glo_class))
        return 'instance method called', self
    
    def set_class_variable(self):
        MyClass.glo_class = 99

    def print_glo_class(self):
        print('instance: ', self.glo_class)
        print('class: ', MyClass.glo_class)


a = MyClass()
a.method()
a.set_class_variable()
a.print_glo_class()
b = MyClass()
b.method()
b.print_glo_class()

User avatar
jadro
Posts: 395
Joined: Sun Oct 02, 2016 1:20 pm
Location: Croatia

Re: Class questions

Mon Feb 11, 2019 8:24 pm

Thanx MrYsLab, great to know that my class variable is copied into instance variable with same name, I didn't know that.

Thanx,
Jadro
Oracle backend database developer
SmartHome IoT & Microprocessor enthusiast and hobbyist

Return to “Python”