1

I am given an object a of the class A. I do not understand how class A works. Furthermore an unknown number of methods throughout the module I am using use A. So for all practical purposes A is unknown and we can only manipulate an instance of it and one known method, method2.

I am given an instance a. I want to convert a to a class B such that it remains identical in every respect except that method2 (which was present in the original class A and prints a) now prints b. How do I modify the piece of code below to be able to do that ?

class B(A):
    def __init__(self,**kwargs):
        super().__init__(**kwargs)

    def method2(self):
        print('b')

a.method1() #prints '1'
a.method2() #prints 'a'
print(a[0]) #prints 1
#a = convertAtoB(a)
a.method1() #prints '1'
a.method2() #should print 'b'
print(a[0]) #prints 1

I am aware of a previous answer to a similar question which involved using __getattr__ however when trying the below piece of code:

class B(object):
    def __init__(self, a):
        self.__a = a

    def __getattr__(self, attr):
        return getattr(self.__a, attr)

    def __setattr__(self, attr, val):
        object.__setattr__(self, attr, val)
    
    def method2(self):
        print('b')

I got, in the practical problem I am having, the error TypeError: 'B' object is not subscriptable.

edit : added a subscript test, as I mentioned above, I don't entirely understand how A works or which methods in the imported module need A to work.

3
  • Your code works for me (though your __setattr__() and __getattr__() don't match - you wouldn't be able to get a property you set via __setattr__()). The error 'B' object is not subscriptable occurs when you try to use square-bracket notation (e.g. B[2]) and the __getattribute__() method is not defined. Is there some code you haven't shown us where that's happening? Commented Sep 13, 2021 at 16:52
  • A is from an imported module, I don't know exactly where it is used or how it works. I only realized after trying the code above that it was subscriptable. Commented Sep 13, 2021 at 16:57
  • "I want to convert a to a class B such that it remains identical in every respect except that method2 (which was present in the original class A and prints a) now prints b" What problem do you solve by doing this? Especially if you don't understand the A class in the first place? Also, where do you expect the data to come from for data that is part of B but not part of A? Commented Sep 13, 2021 at 17:03

2 Answers 2

3

You can reassign object's __class__ to a new type. I've put comment inside the code: (take care of object initialization yourself if necessary)

class A:
    def func_A_1(self):
        return 'func_A_1 is running'

    def func_A_2(self):
        return 'func_A_2 is running'

    def method2(self):
        return 'method2 of class A'


class B(A):
    def method2(self):
        return 'method2 of class B'


obj = A()

print(obj)
print(obj.func_A_1())
print(obj.method2())
print('------------------------------')

# turning object of A to B
obj.__class__ = B
print(obj)

# still have access to A's methods
print(obj.func_A_1())

# This method is now for B
print(obj.method2())

output :

<__main__.A object at 0x0000012FECFACFD0>
func_A_1 is running
method2 of class A
------------------------------
<__main__.B object at 0x0000012FECFACFD0>
func_A_1 is running
method2 of class B
Sign up to request clarification or add additional context in comments.

Comments

0

Don't override __init__, only override method2, and just set a = B(). Or:

class B(A):

    def method2(self):
        print('b')

def convertAtoB(a):
    a.method2 = B().method2
    return a

a.method1() #prints '1'
a.method2() #prints 'a'
#a = convertAtoB(a)
a.method1() #prints '1'
a.method2() #should print 'b'

1 Comment

I managed to get this to work by setting : ``` def convertAtoB(a): def method2(self): print('b') a.method2 = method2 return a a = convertAtoB(a) ``` However the other answer was more inline with what I was originally aiming for (as it allowed for a B subclass).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.