Вопрос

I have a shared resource with high initialisation cost and thus I want to access it across the system (it's used for some instrumentation basically, so has to be light weight). So I created a module managing the setup and access to it. It does a lazy initialise of the resource and stores it in a module global variable. I then use functions of this module across the system to operate on the resource.
- Now I am wondering whether (or how often) I will have to reinitialise the resource?
- I know objects are garbage collected in CPython on (or better around) zero reference count, but is storing in an module counted as a reference, even if the module is not being executed at the moment?

Example with code: here we have the module, where _connect() is slow. I want to use report_safely() across my system and end up calling _connect() as seldom as possible.

__metrics = None


def _connect():
    global __metrics

    client = SomeSlowToSetUpClient()
    __metrics = SomeMetrics(client)
    client.connect()


def report_safely():
       if not __metrics:
           _connect()

       __metrics.execute_lightweight_code()
Это было полезно?

Решение

Objects that are no longer referenced are indeed garbage collected (they are deleted automatically when their reference count drops to 0).

A module global, however, will never have it's reference count drop to 0; once imported a module object (its namespace), lives in the sys.modules mapping. The namespace itself refers to your object.

In other words, your object lives on forever, until you either delete it from the module namespace, delete the module namespace itself (del sys.modules['yourmodule']) or your python script exits.

Другие советы

If the module containing the global is in scope from the start of your execution to the end then the globals will be to. Might be cleaner to use a class instance though.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top