How to deal with class __init__ method that generate from type() function?

22 Views Asked by At

I write a class C generate from type, it can use; but when I write another class D inherit from C, an
error that miss required positional argument occurred. so, I tried to use normal inherit way to rewrite class E and F, and it works fine! so, I want to know what's the difference? this is my code:

class A:
    def __init__(self, value_a):
        self.value_a = value_a

class B(A):
    def __init__(self, value_a, value_b):
        super().__init__(value_a)
        self.value_b = value_b



def c_init(obj, value_a, value_b, value_c):
    super(obj.__class__, obj).__init__(value_a, value_b)
    obj.value_c = value_c

C = type('C', (B,), {'__init__': c_init})

import inspect

params = inspect.signature(C.__init__).parameters
print()

for param in params.values():
    print(f'parma name:{param.name}, anno:{param.annotation}, default:{param.default}')

class D(C):
    def __init__(self, value_a, value_b, value_c, value_d):
        super().__init__(value_a, value_b, value_c)
        self.value_d = value_d

class E(B):
    def __init__(self, value_a, value_b, value_e):
        super().__init__(value_a, value_b)
        self.value_e = value_e

class F(E):
    def __init__(self, value_a, value_b, value_e, value_f):
        super().__init__(value_a, value_b, value_e)
        self.value_f = value_f

f = F(1, 2, 3, 4)
print(f.value_a)
print(f.value_f)

d = D(1, 2, 3, 4)
print(d.value_a)
print(d.value_d)

this is exception:

test_4.py:131 (Test4.test_inherit)
self = <tests.test_4.Test4 testMethod=test_inherit>

def test_inherit(self):
    class A:
        def __init__(self, value_a):
            self.value_a = value_a

    class B(A):
        def __init__(self, value_a, value_b):
            super().__init__(value_a)
            self.value_b = value_b



    def c_init(obj, value_a, value_b, value_c):
        super(obj.__class__, obj).__init__(value_a, value_b)
        obj.value_c = value_c

    C = type('C', (B,), {'__init__': c_init})

    import inspect

    params = inspect.signature(C.__init__).parameters
    print()

    for param in params.values():
        print(f'参数名:{param.name}, 参数类型:{param.annotation}, 默认值:{param.default}')

    class D(C):
        def __init__(self, value_a, value_b, value_c, value_d):
            super(self.__class__, self).__init__(value_a, value_b, value_c)
            self.value_d = value_d
    
>       d = D(1, 2, 3, 4)

test_4.py:163: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
test_4.py:160: in __init__
    super(self.__class__, self).__init__(value_a, value_b, value_c)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

obj = <tests.test_4.Test4.test_inherit.<locals>.D object at 0x000001D3C74CDC70>
value_a = 1, value_b = 2, value_c = 3

    def c_init(obj, value_a, value_b, value_c):
>       super(obj.__class__, obj).__init__(value_a, value_b)
E       TypeError: c_init() missing 1 required positional argument: 'value_c'

test_4.py:145: TypeError

Process finished with exit code 1

I want to know python class inherit how to works when I use type() make obj,and can i find a solution in this way? thank you watch this question!

0

There are 0 best solutions below