Home > Net >  How to pass arguments to a method called from another module?
How to pass arguments to a method called from another module?

Time:01-09

I have the following two modules (simplified):

# Module A
class Transaction:

    def __init__(self, path, ):

        self.logger = logging.getLogger("Transaction")

        logging.basicConfig(level=logging.DEBUG)
        self.path = path
        self.input_1 = None
        self.input_2 = None
        self.input_3 = None
        self.input_merged = None
        self.output = None

    def import_input_data_1(self):
        self.input_1 = pd.read_excel(
            self.path
              country.__data_paths__["collection"]["input"]["transaction"][
                "fy2"
            ],
            index_col=False,
            engine="openpyxl",
            dtype=object,
        )
        return self.input_1

    def import_input_data_2(self):
        self.input_2 = pd.read_excel(
            self.path
              country.__data_paths__["collection"]["input"]["transaction"][
                "fy1"
            ],
            index_col=False,
            engine="openpyxl",
            dtype=object,
        )
        return self.input_2

    def import_input_data_3(self):
        self.input_3 = pd.read_excel(
            self.path
              country.__data_paths__["collection"]["input"]["transaction"][
                "fy"
            ],
            index_col=False,
            engine="openpyxl",
            dtype=object,
        )
        return self.input_3

    def merge_input_data(self):
        self.input_merged = pd.concat(
            [self.input_1, self.input_2, self.input_3]
        )
        return self.input_merged

    def main(self):
        self.logger.info("Loading input data 1")
        self.input_1 = self.import_input_data_1()

        self.logger.info("Loading input data 2")
        self.input_2 = self.import_input_data_2()

        self.logger.info("Loading input data 3")
        self.input_3 = self.import_input_data_3()

        self.logger.info("Merging input data")
        self.input_merged = self.merge_input_data()
# Module B
from A import Transaction
collection = Transaction()

class TestTransaction(object):

    def __init__(self, path):

        logging.basicConfig(level=logging.DEBUG)
        self.path = path
        self.input_1 = None
        self.input_2 = None
        self.input_3 = None
        self.input_merged = None
        self.output = None

    def import_test_input_data(self):
        self.input_1 = pd.read_excel(
            self.path
              test.__data_paths__["collection"]["test"]["input"][
                "fy2"
            ],
            index_col=False,
            engine="openpyxl",
            dtype=object,
        )

        self.input_2 = pd.read_excel(
            self.path
              test.__data_paths__["collection"]["test"]["input"][
                "fy1"
            ],
            index_col=False,
            engine="openpyxl",
            dtype=object,
        )

        self.input_3 = pd.read_excel(
            self.path
              test.__data_paths__["collection"]["test"]["input"][
                "fy"
            ],
            index_col=False,
            engine="openpyxl",
            dtype=object,
        )

        return self.input_1, self.input_2, self.input_3

    def test_merge_input_data(self) -> None:
        collection.merge_input_data()

def main(self):

        self.input_1, self.input_2, self.input_3 = self.import_test_input_data()

        self.input_1, self.input_2, self.input_3 = self.merge_input_data()

Using module B, I want to call the method merge_input_data() from module A, pass arguments from my current instance in B (self.input_1, self.input_2, self.input_3) to the method in A and execute the functionality of merge_input_data() with these arguments. However, I keep getting the error:

All objects passed were None

I want to ask if there is a way to call methods from other modules / classes without them having all to-be-passed arguments explicitly listed, e.g. merge_input_data(self.input_1, self.input_2, self.input_3)? This is because the method from module A usually only takes self as an argument due to it being provided in the instance of A itself, but I want to access it from another module B. Thanks!

CodePudding user response:

You can use @staticmethod to create function belonging to a class which do not need the attributes of a class.

For example:

# Module A
class Collection:
    def _merge_input_data(self):
        self.input_merged = self.merge_input_data(self.input_1, self.input_2, self.input_3)

    @staticmethod
    def merge_input_data(*args):
        return pd.concat(list(args))

# Module B

from Module A import Collection

class Testing:
    def test_merge_input_data(self):
        result = Collection.merge_input_data(FIRST, SECOND, THIRD, ...)

I have add the function Collection._merge_input_data which can be used for an instance of the class. But you did not provide all the code so I am not sure of you used this function from your class or not.

Also in module B you should provide a list with inputs to merge.

CodePudding user response:

It looks like you are wanting to substitute test data for the actual data that the real class Transaction: collects in its import_input_data_x() methods.

Its looks like you've prepared this data in import_test_input_data() in your test class.

You should use this data:

def test_merge_input_data(self) -> None:
    self.import_test_input_data():
    collection.input_1 = self.input_1
    collection.input_2 = self.input_2
    collection.input_3 = self.input_3
    collection.merge_input_data()
  • Related