|
| 1 | +'''Ooh! The Super() Function. What does that do?''' |
| 2 | + |
| 3 | +# Here is the simplest way, I had learned how to use the |
| 4 | +# super() function in Python. I created separate python |
| 5 | +# program examples to, not only walk you through the |
| 6 | +# process of what the super() function is, but to also walk |
| 7 | +# myself through it so I could know what it means and how |
| 8 | +# to use it. Now, I hope I can turn 'can' into 'could' for others, |
| 9 | +# such as myself, who watched different examples on Youtube, |
| 10 | +# or in online Python programming text examples. But to |
| 11 | +# truly understand what the super() function is, you have to |
| 12 | +# start small, then gradually apply the super() function as you |
| 13 | +# learn, or brush up on classes and class inheritance. Because |
| 14 | +# when we learn to apply the super() function, you will have |
| 15 | +# to fully understand what class inheritance is first. But believe |
| 16 | +# it or not, it's quite easy to understand, but you need to start |
| 17 | +# with small classes and class inheritance examples first to |
| 18 | +# get you going. These super() function Python program |
| 19 | +# examples were quite the puzzle to understand for me, and |
| 20 | +# still are to this day; four years later, I'm still trying to master |
| 21 | +# the super() function technique in Python. However, I hope |
| 22 | +# I've helped others understand this super() function Python |
| 23 | +# puzzle just a wee bit more than before, such as myself. |
| 24 | + |
| 25 | +# Here are three separate, single classes with a simple function |
| 26 | +# inside each of them. Each class is called by its own name, along |
| 27 | +# with its own function name alike. Fore example: A.first(); A is the |
| 28 | +# name of the class and first() is the name of the function. You can |
| 29 | +# give any name you wish to classes and functions; they don't have |
| 30 | +# to be called A, B or Mom, Dad or Child. However it's a grand start |
| 31 | +# to teach yourself how to understand what classes and functions |
| 32 | +# do in Python. Python is practically based on using functions, |
| 33 | +# hence the term Object Oriented Programming. |
| 34 | + |
| 35 | +class A: |
| 36 | + def first(): |
| 37 | + print('A') |
| 38 | + |
| 39 | +class B: |
| 40 | + def second(): |
| 41 | + print('B') |
| 42 | + |
| 43 | +class C: |
| 44 | + def third(): |
| 45 | + print('C') |
| 46 | + |
| 47 | +# Let's call each class by its own name and function name |
| 48 | +# alike. |
| 49 | + |
| 50 | +A.first() |
| 51 | +B.second() |
| 52 | +C.third() |
| 53 | + |
| 54 | +# Let's add a child class so we can create a class inheritance, |
| 55 | +# which will inherit each of these class attributes under one, |
| 56 | +# single child class act; ABC is the child class, A, B and C are |
| 57 | +# parent classes. Let's expand more about class inheritance |
| 58 | +# in the next Python program examples, using the dunder |
| 59 | +# init method: __init__ or constructor. |
| 60 | + |
| 61 | +class ABC(A,B,C): # class inheritance |
| 62 | + pass |
| 63 | + |
| 64 | +ABC.first() |
| 65 | +ABC.second() |
| 66 | +ABC.third() |
| 67 | + |
| 68 | +# Let's try some of the same things, but with the use of the |
| 69 | +# return statement that returns values from inside of functions. |
| 70 | + |
| 71 | +class A: |
| 72 | + def first(letter): |
| 73 | + return letter |
| 74 | + |
| 75 | +class B: |
| 76 | + def second(letter): |
| 77 | + return letter |
| 78 | + |
| 79 | +class C: |
| 80 | + def third(letter): |
| 81 | + return letter |
| 82 | + |
| 83 | +a=A.first('A') |
| 84 | +b=B.second('B') |
| 85 | +c=C.third('C') |
| 86 | + |
| 87 | +print(a) |
| 88 | +print(b) |
| 89 | +print(c) |
| 90 | + |
| 91 | +class ABC(A,B,C): # class inheritance |
| 92 | + pass |
| 93 | + |
| 94 | +a=ABC.first('A') |
| 95 | +b=ABC.second('B') |
| 96 | +c=ABC.third('C') |
| 97 | + |
| 98 | +# Let's try some more of the same things, with the use of the |
| 99 | +# return statement that returns objects from inside of functions. |
| 100 | + |
| 101 | +class A: |
| 102 | + def first(object): |
| 103 | + return 'A' |
| 104 | + |
| 105 | +class B: |
| 106 | + def second(object): |
| 107 | + return 'B' |
| 108 | + |
| 109 | +class C: |
| 110 | + def third(object): |
| 111 | + return 'C' |
| 112 | + |
| 113 | +a=A.first(object) |
| 114 | +b=B.second(object) |
| 115 | +c=C.third(object) |
| 116 | + |
| 117 | +print(a) |
| 118 | +print(b) |
| 119 | +print(c) |
| 120 | + |
| 121 | +class ABC(A,B,C): # class inheritance |
| 122 | + pass |
| 123 | + |
| 124 | +a=ABC.first(object) |
| 125 | +b=ABC.second(object) |
| 126 | +c=ABC.third(object) |
| 127 | + |
| 128 | +print(a) |
| 129 | +print(b) |
| 130 | +print(c) |
| 131 | +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' |
| 132 | +# This Parent1, Parent2 and Child class example doesn't |
| 133 | +# invoke the super() function at all. Each parent class gets |
| 134 | +# called by their individual class names, via the Child class. |
| 135 | +# The '__init__' method or constructor initiates the function's |
| 136 | +# attributes so they can retrieve their values, such as the |
| 137 | +# name attribute, which retrieves the values 'Bob' and 'Rob'. |
| 138 | +# The word 'self' is simply telling the def function to call itself |
| 139 | +# so it can retrieve its own attributes and values alike. |
| 140 | + |
| 141 | +class Parent1: |
| 142 | + def __init__(self,name): |
| 143 | + print('Parent1 __init__',name) |
| 144 | + |
| 145 | +class Parent2(Parent1): |
| 146 | + def __init__(self,name): |
| 147 | + print('Parent2 __init__',name) |
| 148 | + |
| 149 | +class Child(Parent2): |
| 150 | + def __init__(self): |
| 151 | + Parent1.__init__(self,'Bob') |
| 152 | + Parent2.__init__(self,'Rob') |
| 153 | + |
| 154 | +Child() |
| 155 | + |
| 156 | +# Why not use this instead? |
| 157 | + |
| 158 | +class Parent1: |
| 159 | + def __init__(self,name): |
| 160 | + print('Parent1 __init__',name) |
| 161 | + |
| 162 | +class Parent2: |
| 163 | + def __init__(self,name): |
| 164 | + print('Parent2 __init__',name) |
| 165 | + |
| 166 | +class Child(Parent1,Parent2): # kill two birds with one child class |
| 167 | + def __init__(self): |
| 168 | + Parent1.__init__(self,'Bob') |
| 169 | + Parent2.__init__(self,'Rob') |
| 170 | + |
| 171 | +Child() |
| 172 | +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' |
| 173 | +# Let's now use the super() function within our classes. |
| 174 | +# The super() function calls Attributes from another class, |
| 175 | +# which allow us to 'reuse our class attributes again and |
| 176 | +# again. Remember, programmers hate to recreate code |
| 177 | +# and they love to reuse code whenever possible. The |
| 178 | +# super() function allows us to treat classes in the same |
| 179 | +# fashion. Also, the super() function allows us to call class |
| 180 | +# constructors ie: __init__ which cannot be called from other |
| 181 | +# classes without using the super() function. |
| 182 | + |
| 183 | +class Parent1: |
| 184 | + def __init__(self,name): |
| 185 | + print('Parent1 __init__',name) |
| 186 | + |
| 187 | +class Parent2(Parent1): |
| 188 | + def __init__(self,name): |
| 189 | + print('Parent2 __init__',name) |
| 190 | + super().__init__('Bob') |
| 191 | + |
| 192 | +class Child(Parent2): |
| 193 | + def __init__(self): |
| 194 | + super().__init__('Rob') |
| 195 | + |
| 196 | +Child() |
| 197 | + |
| 198 | +# Why not use this instead? |
| 199 | + |
| 200 | +class Parent1: |
| 201 | + def __init__(self,name): |
| 202 | + print('Parent1 __init__',name) |
| 203 | + |
| 204 | +class Parent2: |
| 205 | + def __init__(self,name): |
| 206 | + print('Parent2 __init__',name) |
| 207 | + super().__init__('Bob') |
| 208 | + |
| 209 | +class Child(Parent2,Parent1): # kill two birds with one child class |
| 210 | + def __init__(self): |
| 211 | + super().__init__('Rob') |
| 212 | + |
| 213 | +Child() |
| 214 | +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' |
| 215 | +class Base_Class_Attributes: |
| 216 | + def __init__(self,attribute1,attribute2,attribute3): |
| 217 | + self.attribute1=attribute1, |
| 218 | + self.attribute2=attribute2, |
| 219 | + self.attribute3=attribute3 |
| 220 | + |
| 221 | + print('My',attribute1+',',attribute2,'and my',attribute3) |
| 222 | + |
| 223 | +# These work just fine, but there is way too much base class calling |
| 224 | +# redundancy. Three tips to remember. Never recreate code. Always |
| 225 | +# reuse code. Keep it DRY (Don't Repeat Yourself) |
| 226 | + |
| 227 | +Base_Class_Attributes('attribute value 1','attribute value 2','attribute value 3') |
| 228 | +Base_Class_Attributes('Reuse my attribute1','Reuse my attribute2','Reuse my attribute3') |
| 229 | +Base_Class_Attributes('Alright!','Enough is enough!','Redundancy is bad!') |
| 230 | + |
| 231 | +# Why not consider using the super() function instead to avoid base |
| 232 | +# class calling redundancy. |
| 233 | + |
| 234 | +class Base_Class_Attributes: |
| 235 | + def __init__(self,attribute1,attribute2,attribute3): |
| 236 | + self.attribute1=attribute1, |
| 237 | + self.attribute2=attribute2, |
| 238 | + self.attribute3=attribute3 |
| 239 | + |
| 240 | + print('My',attribute1+',',attribute2,'and my',attribute3) |
| 241 | + |
| 242 | +class Call_Base_Class_Attributes(Base_Class_Attributes): |
| 243 | + def __init__(self): |
| 244 | + super().__init__('attribute value 1','attribute value 2','attribute value 3') |
| 245 | + super().__init__('Reuse my attribute1','Reuse my attribute2','Reuse my attribute3') |
| 246 | + super().__init__('Super!','Super!','Excellent!') |
| 247 | + |
| 248 | +Call_Base_Class_Attributes() # No more redundant base class calling. |
| 249 | + |
| 250 | +# Super Duper! |
| 251 | +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' |
| 252 | +class Pets: |
| 253 | + def __init__(self,dog,cat,bird,fish): |
| 254 | + self.dog=dog;self.cat=cat |
| 255 | + self.bird=bird;self.fish=fish |
| 256 | + |
| 257 | + print(f'My {dog}, my {cat}, my {bird} \ |
| 258 | +and my {fish} are GREAT pets to have.') |
| 259 | + |
| 260 | +class Needs: |
| 261 | + def __init__(self,cage,food,water,love): |
| 262 | + self.cage=cage;self.food=food |
| 263 | + self.water=water;self.love=love |
| 264 | + |
| 265 | + print(f'You need a {cage}, some {food}, \ |
| 266 | +some {water} and some {love} are all you need.') |
| 267 | + |
| 268 | +class Toys: |
| 269 | + def __init__(self,bones,ball,squeak_toy,mouse_toy): |
| 270 | + self.bones=bones;self.ball=ball |
| 271 | + self.squeak_toy=squeak_toy |
| 272 | + self.mouse_toy=mouse_toy |
| 273 | + |
| 274 | + print(f'Dogs need to chew {bones} and play \ |
| 275 | +with a {ball}. \nCats need to play with a {mouse_toy}; \ |
| 276 | +while birds love to play with {squeak_toy}.') |
| 277 | + |
| 278 | +class Super1(Pets): |
| 279 | + def __init__(self): |
| 280 | + super().__init__('German Shepherd', |
| 281 | + 'Tabby','Parrot','Angelfish') |
| 282 | + |
| 283 | +class Super2(Needs): |
| 284 | + def __init__(self): |
| 285 | + super().__init__('Cage','Food','Water', |
| 286 | + 'Unconditional Love') |
| 287 | + |
| 288 | +class Super3(Toys): |
| 289 | + def __init__(self): |
| 290 | + super().__init__('Bones','Bouncy Ball', |
| 291 | + 'Squeaky Toys','Mouse Toys') |
| 292 | + |
| 293 | +# Call each class called Super1(), Super2() and Super3() |
| 294 | + |
| 295 | +Super1() |
| 296 | +Super2() |
| 297 | +Super3() |
| 298 | + |
| 299 | +# Why not create a tuple that can loop through each class? |
| 300 | + |
| 301 | +super_loop_tuple=(Super1,Super2,Super3) |
| 302 | + |
| 303 | +# You can also call up any tuple elements in the super_loop_tuple |
| 304 | +# starting at position zero, through positon two. |
| 305 | + |
| 306 | +super_loop_tuple[0]() |
| 307 | +super_loop_tuple[1]() |
| 308 | +super_loop_tuple[2]() |
| 309 | + |
| 310 | +# Create a for-loop that can loop through each class instead. |
| 311 | +# Let's use our super_loop_tuple for this |
| 312 | + |
| 313 | +for i in super_loop_tuple: |
| 314 | + (i()) |
0 commit comments