On 2024-03-11 16:53:00 -0400, Ivan "Rambius" Ivanov via Python-list wrote:
I am refactoring some code and I would like to get rid of a global
variable. Here is the outline:
...
The global cache variable made unit testing of the lookup(key) method
clumsy, because I have to clean it after each unit test. I refactored
it as:
class Lookup:
def __init__(self):
self.cache = {}
def lookup(key):
if key in self.cache:
return self.cache[key]
value = None
cmd = f"mycmd {key}"
proc = subprocess(cmd, capture_output=True, text=True, check=False)
if proc.returncode == 0:
value = proc.stdout.strip()
else:
logger.error("cmd returned error")
self.cache[key] = value
return value
Now it is easier to unit test, and the cache is not global. However, I
cannot instantiate Lookup inside the while- or for- loops in main(),
because the cache should be only one. I need to ensure there is only
one instance of Lookup - this is why I made it a global variable, so
that it is accessible to all functions in that script and the one that actually needs it is 4 levels down in the call stack.
[...]
I am looking for the same behaviour as logging.getLogger(name). logging.getLogger("myname") will always return the same object no
matter where it is called as long as the name argument is the same.
How would you advise me to implement that?
Just add a dict of Lookup objects to your module:
lookups = {}
def get_lookup(name):
if name not in lookups:
lookups[name] = Lookup()
return lookups[name]
Then (assuming your module is also called "lookup", in all other modules
do
import lookup
lo = lookup.get_lookup("whatever")
...
v = lo.lookup("a key")
In your test cases where you need many different lookup tables use
lo = lookup.get_lookup("test1")
...
lo = lookup.get_lookup("test2")
...
lo = lookup.get_lookup("test3")
hp
PS: You don't have to put that in a separate module but I think it's a
lot cleaner that way.
--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | |
[email protected] | -- Charles Stross, "Creative writing
__/ |
http://www.hjp.at/ | challenge!"
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEETtJbRjyPwVTYGJ5k8g5IURL+KF0FAmXvlaQACgkQ8g5IURL+ KF3XYBAAnXGsZsJfRJVxP+RX6kFJzhLVDYaHQV8dp8gpXX4XvKCCBo56Q2OyUqmk TDXhsn/GBpNIrPWmYmPAiL8pLSV3MbcON1ABGT9KgB+pxO8KnYVpH7Il6uV6zT8H ZvEXJwX8qjD5OtZIJ5q4pLaYW4A2l+8vvNS+pYqhFMOkRsteKld4XBVblw/+ME3/ 5Kat7h1/eoa4UVkHNgxB1FEWWKH6nXbXGgdM+khBBdO7SVI6vh9ooPLGZUvNGk8+ VDv3zc0O9fauEPzfPlBnSZQiyxCFyEgs0XF0hAMGQCadm5EZXHMu1dKi8+me0he3 laTb6DX9iiZbvbPVhITGmEh3UyaqAjYLfrhQ89Vwj2n1piKX611UNayWaUCVMVPy KfL1/lmaMc7Z1LJsOZG+kHTmSbGi6f9OTJpFZwJYOD5VP0SWVPyLGaJuO1azkP+c +tFYpm6UXPREFOsK8mSejWiQF5/klRCWLjjqS5rNfrsjp1I+lerUL/B3/bXTHc95 phoMSuRiuBqbmNzEOUm9dxSbVWkcWIOT6cgPZnpdGdJp7hdKShbTG854X4Zlli8l rVC1IfEn5ZIxLedVrMNccX2NDhEdyIAQuSYmtW2EJ7P2wnz/wsf3GFtyZpQrop9u +pLPOUH4HusZzOvro/AqZQcxCO+57+F9P4i4xcv