pythonoop

Is it possible to pass a class or object as a parameter in a function?


In Python, we can set functions to take certain types as parameters (for e.g. calc_cost(rate:float)). I was wondering if I could do the same by specifying a class of object.

I'm working on a game where I have defined a function which takes several objects. I want to specify the type of object (a class it will take as a parameter. But whenever I have tried to implement classes in a function it never works.

Here's a small dummy program:

class Store:
    def calc_cost(rate: float, qty: int) -> float:
        return rate * qty
    
def sum_stores(store1, total):
    total += store1.calc_cost(15, 30)

total = 0

ice_cream_shop = Store()
sum_stores(ice_cream_shop, total)

The answer should be a number, but I am getting this:

TypeError: sum_stores() takes 2 positional arguments but 3 were given

I have only given 2 arguments but Python detects 3. This only happens when I add an instance of a class. What is the problem, and how can I solve it? And if this has nothing to do with classes as parameters, how can I implement them if possible?


Solution

  • You didn't define the instance method correctly. It will be given an implicit argument of type Store, but you must explicitly define the function to accept it, even if you don't use or need it.

    class Store:
        def calc_cost(self, rate: float, qty: int) -> float:
            return rate * qty
        
    

    You can't update an int argument in place; instead, return the value of store1.calc_cost to be added to a variable in the calling scope.

    def sum_stores(store1):
        return store1.calc_cost(15, 30)
    
    total = 0
    
    ice_cream_shop = Store()
    total += sum_stores(ice_cream_shop)
    

    It might make more sense for each store to maintain its own total (which would give calc_cost, or a suitable renamed version of it, a reason to be an instance method). For example,

    class Store:
        def __init__(self):
            self.total = 0
    
        def update_total(self, rate: float, qty: int):
            self.total += rate * qty
    
    
    ice_cream_shop = Store()
    ice_cream_shop.update_total(15, 30)
    assert ice_cream_shop.total == 450