Reputation: 7091
A bit of a complex problem to describe here:
I would like to have a function AB(), which maps one input to another, through an intermediate value. More specifically, the function is made up of two function, let's call A() and B(), which both return dictionaries (ie. A[B[input]] --> result)
This is an example of my current file directory:
packageX/
__init__.py
get_part_of_B_expensively.py
something_that_will_use_convert.py
convert.py
packageA/
__init__.py
get_the_entirety_of_A_expensively.py
In my convert.py I have the following:
import get_part_of_B_expensively
from packageA import get_the_entirety_of_A_expensively
dict_A = packageA.get_the_entirety_of_A_expensively()
def get_B():
result = {}
result = get_part_of_B_expensively() # this is a very expensive operation
result += get_rest_of_B_inexpensively() # shorthand for adding two dictionaries
return result # returns a dictionary
dict_B = get_B() # hence why i call it once outside, and not inside AB()
def AB(input):
return dictA[dictB[input]]
Don't think this is proper since I can't initialize dict_B before defining get_B(), and I want AB()'s only parameter to be input
, since I want to abstract its implementation. However, I introduce a few variables globally, mainly dict_B and dictA, and I'm not sure if that's the best way to do it. I can separate get_B() into its own package, but I would still be left calling them somewhere in the global frame. Not sure what the approach to this should be, I want to call A() and B(), which calls a file in the same package) as few times as possible but abstract the function AB().
Upvotes: 1
Views: 878
Reputation: 251538
If this is all your module is doing, I wouldn't say it's that bad to keep it that way. For small scripts that are just manipulating specific data, sometimes using a global is okay, especially if you're using it as read-only. (A lot of the confusing problems with globals arise when you need to mutate them or rebind them.) There are plenty of respectable libraries that have global variables storing various sorts of global parameters, such as customization options loaded from config files, etc.
For a more heavyweight situation, if your task were more complex, you could create a class that basically does this:
class Convert(object):
def __init__(self):
self.A = packageA.get_the_entirety_of_A_expensively()
self.B = getB() # or put get_B's code in here
def AB(self, input):
return self.A[self.B[input]]
converter = Convert()
converter.AB('blah')
This could be overkill if you just need to do one thing, but it's the way to go if you need to parameterize the operation (e.g., if you had multiple A and B dicts that you might need to operate on).
Upvotes: 3