jeudi 10 septembre 2020

Should Python Object methods be given what they need as params, or can they be accessed from self internally?

So if we have an Object we need to do some complex processing in stages should we

  1. Create an object with the steps and fill up the internal state and use self all the time internally
class MyObjectNoParams(object):

    def __init__(self, date):
        self.date = date
        self.a_dict = {}
        self.obj1 = Obj1()
        self.obj2 = Obj2()
        self.b = None
        self.c = None
        self.d = None
        self.e = None
        self.f = None
        self.g = None

    def run(self):
        self.do_thing_1()
        self.do_thing_2()
        self.do_thing_3()
        self.do_thing_4()

    def get_data(self):
        self.a_dict['example_key'] = 'val'

    def do_thing_1(self):
        # do something
        self.b = examplelib.do_stuff_1(self.date)

    def do_thing_2(self):
        self.c = examplelib.do_stuff_2(self.obj1.method(self.date), self.b)

    def do_thing_3(self):
        self.d = self.a_dict['example_key'] * self.b * self.c

    def do_thing_4(self):
        examplelib.save_something(self.d)


  1. Make efforts to try to pass in what each function needs, chaining the results of each function together
class MyObjectPassParams(object):

    def __init__(self, date):
        self.date = date

    def run(self):
        b = self.do_thing_1(self.date)
        obj1 = Obj1()
        c = self.do_thing_2(obj1, b)
        example_val = self.get_data()['example_key']
        d = self.do_thing_3(example_val, b, c)
        self.do_thing_4(d)

    def get_data(self):
        a_dict = {}
        a_dict['example_key'] = 'val'
        return a_dict

    def do_thing_1(self, date):
        # do something
        return examplelib.do_stuff_1(date)

    def do_thing_2(self, date, obj1, b):
        return examplelib.do_stuff_2(obj1.method(date), b)

    def do_thing_3(self, example_val, b, c):
        return example_val * b * c

    def do_thing_4(self, d):
        examplelib.save_something(self.d)

I personally think the latter is better as it stops the Object filling up with members as it grows etc. However it is much easier to start off with the first option.

I think the latter also lends itself well to unit testing as a pickled object of the right state isn't needed for each stage

I would love to be pointed at some good reading material around this subject as it doesn't seem like a pure design pattern Gang of Four thing and also I havent seen much in the books I have.

Aucun commentaire:

Enregistrer un commentaire