0

I am kind of stuck using custom class objects within dictionaries.

These are my classes, they work just fine.

from sqllibrary import cursor
from cloudlib import upload

class Mycustomconf(object):
    def __init__(self):
        self.cursor = cursor(foo, bar)

class Mycustomclass1(Mycustomconf):
    def __init__(self):
        super().__init__()

    def something_useful(self, something):
        self.upload(self.cursor(f'''SELECT foo FROM bar WHERE id = {something};'''))

    def something_useful_too(self, something):
        self.upload(self.cursor(f'''SELECT foo FROM bar WHERE id = {something};'''))

class Mycustomclass2(Mycustomconf):
    def __init__(self):
        super().__init__()

    def something_useful(self, something):
        self.upload(self.cursor(f'''SELECT foo FROM bar WHERE id = {something};'''))

    def something_useful_too(self, something):
        self.upload(self.cursor(f'''SELECT foo FROM bar WHERE id = {something};'''))

mcc1 = Mycustomclass1()
mcc2 = Mycustomclass1()

I want to execute one of the methods of each class (Mycustomclass1, Mycustomclass2) based on a condition. I can achieve that with the following script.

from foobar import mcc1, mcc2

def handler(foo, bar):

    try:

        mcc1.something_useful('42', '23')

    except error1 as er:

        mcc1.something_useful_too('42', '22', '11')

    try:

        mcc2.something_useful('42', 42, '23', 12)

    except error1 as er:

        mcc2.something_useful_too(42, '23', 12)
...

handler(foo, bar)
        

That pattern is exactly the same in all the class methods I want to execute (Try "something_useful" except error execute "something_useful_too").

The thing is, I've been trying for a while but I am unable to get the same functionality as the previous code but avoiding that redundant try-except blocks over and over again.

Here is the last thing I've tried before posting:

from foobar import mcc1, mcc2

dict = {"task_a": (mcc1.something_useful('42'),
                   mcc1.something_useful_too('42')),

        "task_b": (mcc2.something_useful('42'),
                   mcc2.something_useful_too('42'))}

def handler(foo, bar):

    for key in dict.keys():

        try:

            dict[key][0]

        except error1 as er:

            dict[key][1]


handler(foo, bar)

The new handler function is much slower for an unknown reason. It appears to call the methods more than once within the for loop but I don't know why is slower that way.

Thanks for correct this error in the comments

I think there might be a cleaner way to perform this that I am not seeing right now. Can anyone post a cleaner approach than mine?

Thank you in advance!

Victor Cid
  • 172
  • 1
  • 7
  • 1
    Why us a dict here? Why not just a list? If the only thing you are going to use it for is iterating over it, just use a list. Anyway, the problem is you are *calling* the methods and putting the result of that in your dict, you aren't putting the methods in your dict. `mcc1.something_useful('42')` calls the method... `mcc1.something_useful` just references the method – juanpa.arrivillaga Mar 24 '21 at 22:12
  • 1
    "The new handler function is much slower for an unknown reason. It appears to call the methods more than once within the for loop but I don't know why is slower that way." No, it doesn't call the methods at all within the for loop. It calls *all* of them, *before putting them in the dict*. – Karl Knechtel Mar 24 '21 at 22:23
  • @juanpa.arrivillaga I have some reasons to use dicts instead of lists in the real code but a quick one is readability. Using task1["context"][0] is far better than tasks[0]. – Victor Cid Mar 25 '21 at 00:05

1 Answers1

1

Currently the methods will be evaluated when the dictionary is declared. You could instead store the options as tuples of function reference and parameter value:

from foobar import mcc1, mcc2

dict = {"task_a": ((mcc1.something_useful, '42')),
                   (mcc1.something_useful_too, '42')),

        "task_b": ((mcc2.something_useful, '42'),
                   (mcc2.something_useful_too, '42'))}

def handler(foo, bar):

    for key in dict.keys():

        try:

            dict[key][0](dict[key][1])

        except error1 as er:

            dict[key][1](dict[key[1])


handler(foo, bar)
jonbush
  • 56
  • 4