Hyperparameters in Python, did you know?

1. Hyperparameters in Python

In Python, super calls a method on another class. When a class inherits from another class, it is called parent class, base class or super class.

Using super is very straightforward, because it goes directly to the parent class and calls its methods.

Arguments can be passed to super. It takes two parameters, a class and a class instance.

Sample code:

class A:
    def roo(self):
        return 'roo() from A'
class B(A):
    def roo(self):
        print('roo() from B')
        return super().roo()
class C(A):
    def roo(self):
        print('roo() from C')
        return super().roo()
class D(B, C):
    def roo(self):
        print('roo() from D')
        return super(C, self).roo()
a=A()
b=B()
c=C()
d=D()
print(a.roo())
print(b.roo())
print(c.roo())
print(d.roo())

output:

roo() from A
roo() from B
roo() from A
roo() from C
roo() from A
roo() from D
roo() from A

2. Super uses the concept of inheritance

If you're not familiar with object-oriented programming concepts, inheritance might seem foreign. In object-oriented programming, inheritance refers to the ability of a class to derive (or inherit) properties and behavior from another class without implementing them again.

A convenient way to understand these concepts is to look at a piece of code, so let's create some classes to describe some shapes.

Sample code:

class Rectangle_Shape:
    def __init__(self, len, wid):
        self.length = len
        self.width = wid
    def area(self):
        return self.length * self.width
    def perimeters(self):
        return 2 * self.length + 2 * self.width
class Square_Shape:
    def __init__(self, len):
        self.length = len
    def area(self):
        return self.length * self.length
    def perimeters(self):
        return 4 * self.length
s=Square_Shape(4)
print(s.area())
r=Rectangle_Shape(3,5)
print(r.area())

This class has two corresponding classes: Rectangle_Shape and Square_Shape.

output:

16
15

This example demonstrates two interrelated shapes: A square is a type of rectangle. The code does not reflect this relationship, resulting in essentially duplicated code.

By using inheritance, you can reduce the amount of code you write while reflecting the real-world relationship between rectangles and squares.

Sample code:

class Rectangle_Shape:
    def __init__(self, length, width):
        self.length = length
        self.width = width
    def area(self):
        return self.length * self.width
    def perimeters(self):
        return 2 * self.length + 2 * self.width
# Making the Square_Shape class that initiates the Rectangle_Shape class
class Square_Shape(Rectangle_Shape):
    def __init__(self, len):
        super().__init__(len, len)
s=Square_Shape(4)
print(s.area())

In this case, super() calls init() of the Rectangle_Shape class, which is then used in the Square_Shape class without having to rewrite the code.

output:

16

As shown in the example, Rectangle_Shape is the parent class and Square_Shape is the child class.

Precise use of hyperparameters in Python

Below is the code for the M, N, and O classes.

class M:
    def __init__(self):
            print("M initiated successfully")
class N(M):
    def __init__(self):
            super().__init__()
            print("N initiated successfully")
class O(N):
    def __init__(self):
            super(O, self).__init__()
            print("O initiated successfully")
o=O()

As the code above assumes, all classes override their immediate parent's init() method. super() doesn't require any attributes, so using it without arguments is enough.

output:

M initiated successfully
N initiated successfully
O initiated successfully

Suppose we want class M2 to skip N''s init() method and run M''s init() method instead. The init() method should inherit from M, not N, even though our class's direct parent is N.

Here is class M2. Let's see it in action.

class M:
    def __init__(self):
            print("M initiated successfully")
class N(M):
    def __init__(self):
            super().__init__()
            print("N initiated successfully")
class O(N):
    def __init__(self):
            super(O, self).__init__()
            print("O initiated successfully")
class M2(N):
    def __init__(self):
            super(N, self).__init__()
            print("other O initiated successfully")
m2=M2()

As can be assumed from the code above, this time we passed attributes to the super() method to select the correct superclass. As a result of running m2 = M2() we get the following output.

M initiated successfully
other O initiated successfully

Instead of calling the immediate superclass __init__() method, we call the M'sinit() Python method.

For implicit lookups using these statements or operators, such as super()[name], super() is undefined.

Also, super() is not restricted to use internal methods other than the zero-argument form. Use the two-argument form to accurately identify the arguments and quote them appropriately.

In a class definition, zero arguments only work because the compiler fills in the necessary details to retrieve the class and instance.

Using Super in Python to pass parameters to constructor multiple inheritance

If you usually deal with various inheritance, a base class should be designed for multiple inheritance.

Sometimes, two classes have similar parameter names. When this happens, you cannot remove key-value pairs from **kwargs, nor from *args.

It is possible to define a Base class which, unlike objects, can absorb/ignore parameters.

Sample code:

class Base(object):
    def __init__(self, *args, **kwargs): pass
class P(Base):
    def __init__(self, *args, **kwargs):
        print("P")
        super(P, self).__init__(*args, **kwargs)
class Q(Base):
    def __init__(self, *args, **kwargs):
        print("Q")
        super(Q, self).__init__(*args, **kwargs)
class R(P):
    def __init__(self, arg, *args, **kwargs):
        print("R","arguments=",arg)
        super(R, self).__init__(arg, *args, **kwargs)
class S(Q):
    def __init__(self, arg, *args, **kwargs):
        print("S", "arguments=",arg)
        super(S, self).__init__(arg, *args, **kwargs)
#Python小白学习交流群:153708845        
class T(R,S):
    def __init__(self, arg, *args, **kwargs):
        print("T", "arguments=",arg)
        super(T, self).__init__(arg, *args, **kwargs)
        print("MRO---", [x.__name__ for x in T.__mro__])
t=T(10)

output:

T arguments= 10
R arguments= 10
P
S arguments= 10
Q
MRO--- ['T', 'R', 'P', 'S', 'Q', 'Base', 'object']

It should be noted that Base must be the penultimate class in MRO for this to work.

The Python programming language provides extensive capabilities for object-oriented programming. In this set of functions, super function parameters play an important role, especially when used correctly.

Hope this article helps you better understand how to use super function parameters in Python.

Guess you like

Origin blog.csdn.net/qdPython/article/details/132250567
Recommended