Home > Net >  Seemingly seperate objects interfere with eachother during initialization
Seemingly seperate objects interfere with eachother during initialization

Time:11-29

I'm 100% sure this is my fault. And I bet it's something really obvious. So believe me when I say I've looked over my code for a while before posting. I just need some help from someone to find the cause of these errors, and I'm sure I'll be able to solve it from there. Maybe just a fresh pair of eyes looking over the code is enough to spot the error quickly.

Using python 3.9

The problem

The first time I create a Command object, all the outputs seem fine. But if I create a second Command object, the output of the first Command object change.

If I for example run this:

test_command = Command("Power to comms", {REGULAR_RESOURCE_NAMES["power"]: Power(value=1)},
                               {REGULAR_RESOURCE_NAMES["comms"]: Comms(value=2)})

I get the following output i the debugger:

Power to comms [Command]
    Input resources: {'Power': <data_structure.Power object at 0x7f17e56e78b0>}
    Output resources: {'Comms': <data_structure.Comms object at 0x7f17e56e77c0>}

But if I afterwards run this:

test_command2 = Command("Comms and power to navs", {REGULAR_RESOURCE_NAMES["comms"]: Comms(value=2),
                                                            REGULAR_RESOURCE_NAMES["power"]: Power(value=1)},
                                {REGULAR_RESOURCE_NAMES["navs"]: Navs(value=5)})

I get the following output in the debugger:

Power to comms [Command]
    Input resources: {'Power': <data_structure.Power object at 0x7f17e57135b0>, 'Comms': <data_structure.Comms object at 0x7f17e5713610>}
    Output resources: {'Comms': <data_structure.Comms object at 0x7f17e56e77c0>, 'Navs': <data_structure.Navs object at 0x7f17e56e78b0>}

Comms and power to navs [Command]
    Input resources: {'Power': <data_structure.Power object at 0x7f17e57135b0>, 'Comms': <data_structure.Comms object at 0x7f17e5713610>}
    Output resources: {'Comms': <data_structure.Comms object at 0x7f17e56e77c0>, 'Navs': <data_structure.Navs object at 0x7f17e56e78b0>}

First of all, we can see that the Power object in both Command objects share the same address. This is not what I have intended. So that's the first error. Secondly, why does the first command suddenly have more input/output resources than before?

I've included the relevant code below:

My code

class Command:
    """
    Contains a ratio for exchanging input resources into output resources
    """

    name: str
    input_resources: dict[str, type(Resource)] = {}
    output_resources: dict[str, type(Resource)] = {}

    def __init__(self, name: str,
                 input_resources: dict[str, type(Resource)], output_resources: dict[str, type(Resource)]):

        self.name: str = name

        for input_resource_name, input_resource in input_resources.items():
            self.input_resources[input_resource_name]: type(Resource) = input_resource.copy()

        for output_resource_name, output_resource in output_resources.items():
            self.output_resources[output_resource_name]: type(Resource) = output_resource.copy()

    def __str__(self) -> str:
        output: str = self.name   " [Command]"   "\n\t" \
                        "Input resources: "   str(self.input_resources)   "\n\t" \
                        "Output resources: "   str(self.output_resources)   "\n"
        return remove_trailing_newlines(output)

    def copy(self) -> type(__name__):
        input_resources_copy: dict[str, type(Resource)] = {}
        for input_resource_name, input_resource in self.input_resources.items():
            input_resources_copy[input_resource_name]: type(Resource) = input_resource.copy()

        output_resources_copy: dict[str, type(Resource)] = {}
        for output_resource_name, output_resource in self.output_resources.items():
            output_resources_copy[output_resource_name]: type(Resource) = output_resource.copy()

        return Command(self.name, input_resources_copy, output_resources_copy)
class Resource:
    """
    The base class for all resource types, such as Comms, Navs, Data, Heat, Drift, Thrust
    """

    name: str
    value: int
    min_value: int
    max_value: int

    def __init__(self, name: str, value: int = 0, min_value: int = 0, max_value: int = 999):
        self.name: str = name
        self.value: int = value
        self.min_value: int = min_value
        self.max_value: int = max_value

    def is_valid_value(self) -> bool:
        """
        Checks if the numerical validity of the resource value based on init parameters
        """
        return self.min_value <= self.value <= self.max_value
class Power(Resource):
    """
    This subclass of Resource, contains variables and methods specific to this particular in-game resource.
    This is what's considered a regular resource.
    """
    def __init__(self, value: int = 0):
        super().__init__(REGULAR_RESOURCE_NAMES["power"], value=value)

    def next_turn(self) -> bool:
        return self.is_valid_value()

    def is_valid_end_of_route(self) -> bool:
        return self.is_valid_value()

    def copy(self) -> type(__name__):
        return Power(value=self.value)

The other resources like Comms, Navs, Data, are exactly the same as the Power class, except for the name.

And the following is instantiated in the global scope:

REGULAR_RESOURCE_NAMES = {
    "comms": "Comms",
    "navs": "Navs",
    "data": "Data",
    "power": "Power"
}

CodePudding user response:

When you define variables for a class like this

class Command:
    """
    Contains a ratio for exchanging input resources into output resources
    """

    name: str
    input_resources: dict[str, type(Resource)] = {}
    output_resources: dict[str, type(Resource)] = {}

these variables are assigned to the class rather than an instance. In your __init__ function, you assign to the class's variable rather than a variable owned by the instance. If you remove the class level definitions, and initialize these separately in the __init__ as Frank mentions below, it should work.

  • Related