Mikoskay
Mikoskay

Reputation: 133

Python3 super() and generic class

I believe a test case is worth a thousand words:

#!/usr/bin/env python3

def generate_a(key):
    class A(object):
        def method(self):
            return {'key': key,}
    return A

BaseForB = generate_a(1337)

class B(BaseForB):
    def method(self):
        dict = super(BaseForB, self).method()
        dict.update({'other_key': 0,})
        return dict

EXPECTED = {'other_key': 0, 'key': 1337,}
RESULT = B().method()

if EXPECTED == RESULT:
    print("Ok")
else:
    print("EXPECTED: ", EXPECTED)
    print("RESULT: ", RESULT)

This raises:

AttributeError: 'super' object has no attribute 'method'

The question is - how to run A.method() in B.method() (the thing I tried to do with super())

edit

Here's more appropriate test case:

#!/usr/bin/env python3

def generate_a(key):
    class A(object):
        def method(self):
            return {'key': key,}
    return A

class B(object):
    def method(self):
        return {'key': 'thisiswrong',}

BaseForC = generate_a(1337)

class C(B, BaseForC):
    def method(self):
        dict = super(C, self).method()
        dict.update({'other_key': 0,})
        return dict

EXPECTED = {'other_key': 0, 'key': 1337,}
RESULT = C().method()

if EXPECTED == RESULT:
    print("Ok")
else:
    print("EXPECTED: ", EXPECTED)
    print("RESULT: ", RESULT)

The question is - how do I choose which parent class I'm interested in?

Upvotes: 3

Views: 11875

Answers (3)

BlackMamba
BlackMamba

Reputation: 10252

class B(BaseForB):
def method(self):
    dict = super(BaseForB, self).method()
    dict.update({'other_key': 0,})
    return dict

is not right, you should write like this:

class B(BaseForB):
def method(self):
    dict = super(B, self).method()
    dict.update({'other_key': 0,})
    return dict

In this situation:

class C(B, BaseForC):
def method(self):
    dict = super(C, self).method()
    dict.update({'other_key': 0,})
    return dict

you must use the old way to call Parent class's function. like this

class C(B, BaseForC):
def method(self):
    dict = B.method(self)
    dict.update({'other_key': 0,})
    return dict

Upvotes: 0

gecco
gecco

Reputation: 18870

Alternatively, you can call the parents method like this:

dict = BaseForC.method(self)

Upvotes: 0

Sven Marnach
Sven Marnach

Reputation: 602775

Your super() call is wrong. it should be

super(B, self).method()

or in Python 3.x also just

super().method()

Furthermore, don't use dict as a variable name -- this will shadow the built-in class.

Upvotes: 14

Related Questions