bfe
bfe

Reputation: 133

Python: Passing a class instance to an external function

I have come across a python project that commonly calls external functions from class methods and passes the class instance and some other parameters to the external function.

The method used is shown in method_one below and I have never come across this implementation before. Using locals to get both the local method parameters and the self class instance seems strange to say the least. The code then relies upon the dictionary keys being named correctly i.e. the same as the parameters of the external function (some_function).

To me, the obvious, simpler direct alternative is method_two but even over that I would prefer either

  1. making some_function a method of ExampleClass1 so it has direct access to self, or
  2. passing only the required attributes of the ExampleClass1 instance to some_function.

Example code:

class ExampleClass1(object):
    def __init__(self, something):
        self.something = something

    def method_one(self, param_1, param_2):
        all_params = locals()
        all_params['example_self'] = all_params.pop('self')
        some_function(**all_params)

    def method_two(self, param_1, param_2):
        some_function(self, param_1, param_2)


def some_function(example_self, param_1, param_2):
    print(example_self.something, param_1, param_2)


e = ExampleClass1("do")
e.method_one(1, "a")
e.method_two(2, "b")

So,

  1. Is there any reason to be using method_one that I'm not aware of?
  2. How would you offer advice on the best practice for this situation?

Upvotes: 2

Views: 2290

Answers (1)

BowlingHawk95
BowlingHawk95

Reputation: 1648

Passing self as a parameter to external functions is a totally standard practice. I'm a little unclear why the call to locals() is used and why keys are being shuffled around, but that's a separate matter. In general, I find that if you're using locals(), then 9 times out of 10 the code you're writing can be simpler. Notable exception being metaprogramming, which is another topic.

One example that I use this for is when you want to separate out code into several modules rather than have one large class with a bunch of methods. There's a lot of ways to organize code, but one approach that I use is to segregate functions to other modules based on their domain, and then pass self to those functions for their use.

Concrete example: a server object accepting requests can have the routes handling those requests live elsewhere, and then delegate the actual business logic to the external route functions. If those routes need the server object, though, then you may want to pass self (being the server) to them. You could make an argument they should just be methods then, but that's a matter of code style and depends a lot on exact use case.

In general, passing self around isn't a bad practice when used appropriately.

Upvotes: 1

Related Questions