Python Forum

Full Version: Copying methods to effect the new owner instead of the old instance
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Here is my code, with a small debug loop...

class foo:
    def __init__(self, message="hello Damien", rotation=0):
        self.message = message
        self.rotation = rotation
        self.target_rotation = rotation

    def rotate(self):
        if self.rotation == 0:
            self.target_rotation = 30
        else:
            self.target_rotation = 0
    
    def great(self):
        print(self.message)

    def change_to(self, other):
        self.message = other.message
        self.rotation = other.rotation
        self.target_rotation = other.target_rotation
        
        self.ability1 = other.ability1
        self.ability2 = other.ability2

    def update(self):
        if self.rotation != self.target_rotation:
            if self.target_rotation == 30:
                self.rotation += 1
            else:
                self.rotation -= 1

    def ability1(self):
        pass
    def ability2(self):
        pass
            
class foo1(foo):
    def ability1(self):
        self.rotate()
    
    def ability2(self):
        self.change_to(foo2)


class foo2(foo):
    def ability1(self):
        self.rotate()
    
    def ability2(self):
        self.great()


foo1 = foo1()
foo2 = foo2(message="hello world")

while True:
    print("-----------")
    print("msg: " + str(foo1.message))
    print("rot: " + str(foo1.rotation))
    print("target_rot: " + str(foo1.target_rotation))
    inp = str(input("> "))
    if inp == "a":
        if foo1.rotation == 0:
            foo1.ability1()
        elif foo1.rotation == 30:
            foo1.ability2()
    # exit ask for input
    print(foo1.target_rotation)
    foo1.update()
So I create foo1 and foo2, then go throught the abilites of foo1, the second ability of foo1 is to change_to foo2 so it does, taking its arguments and its abilites(here is the question), as the ability of foo2 has self so it effects itself as an instance, running self.rotate as the new ability of foo1, will now change the target rotation of foo2 instance instead of foo1, so how can I while keeping this general structure make so when the abilites are copied, they now as self effect the instance instead of the other...

I didnt try much, asking AI, changing to import copy...
I think a composition class would be better.

Below I have a class Chameleon that can be made to behave like a Foo1 object or a Foo2 object. Chameleon is not related in any way to Foo, Foo1 or Foo2, but has an attribute that references a Foo type object. When you call the Chameleon.doit() method it calls the doit() method from whatever object was last assigned to Chameleon.obj.
import abc


class Foo(abc.ABC):
    def __init__(self, value):
        self.value = value

    @abc.abstractmethod
    def doit(self):
        pass


class Foo1(Foo):
    def doit(self):
        print(f"Foo1({self.value})")


class Foo2(Foo):
    def doit(self):
        print(f"Foo2({self.value})")


class Chameleon():
    def __init__(self, obj):
        self.obj = obj

    def doit(self):
        self.obj.doit()


foo1 = Foo1("Hello")
foo2 = Foo2("World")
c = Chameleon(foo1)
c.doit()
c.obj = foo2
c.doit()
foo = Foo()
Output:
Foo1(Hello) Foo2(World) Traceback (most recent call last): File "test.py", line 37, in <module> foo = Foo() ^^^^^ TypeError: Can't instantiate abstract class Foo with abstract method doit
This really looks like a XY question where you ask about your wrong solution X instead of asking about your good problem Y.

You'd get much more accurate answers if you told us what foos really are, and what their abilities really are and why you want to change foo1 into foo2. Use concrete terms, there is most certainly a well known solution to your problem.