3

Are there any ready-to-use Python module that provides an easy to use proxy object that only initializes the "real" object when really needed?

Ideally I'm looking for a transparent implementation so that code dealing with this proxy object does not need to be aware that it is not the actual object.

I want to use it like this:

class Example:
    def __init__(self):
        print("Example initialized")

lazy = Proxy(Example)
print(isinstance(lazy, Example))
# Example initialized
# True

As you can see it would behave very much like a unittest.MagicMock.

If there aren't any libs offering functionality like this out there I'll implement it myself but I want to be sure no one else have done this yet.

EDIT

I expect this proxy object to follow a through implementation like this.

4
  • 1
    django.utils.functional.lazy Commented Feb 6, 2018 at 1:37
  • @Marat This seems to suit my needs. Though there are two downsides: to use it I would need to import the whole DJango module; and their docs does not expose this piece as stable: Most of the modules in django.utils are designed for internal use [...]. While they specify some parts of django.utils as stable for external use, these lazy objects aren't there. But this is a great start regardless, thanks for pointing it out. Commented Feb 6, 2018 at 2:19
  • Looks like the link you included has died. Commented Jan 17, 2024 at 8:14
  • 1
    @MagnusLindOxlund replaced the link with a Web Archive snapshot of the original page. Thanks for pointing it out. Commented Jan 22, 2024 at 14:44

2 Answers 2

5

I've found module lazy-object-proxy which does exactly that.

Worth mentioning that as @Marat pointed out Django offers a solution as well, though I do not want to import Django just for that, if you're already using it in your project it will be a perfectly fine solution.

Sign up to request clarification or add additional context in comments.

Comments

0

There's Werkzeug's LocalProxy:

# external_module.py
from werkzeug.local import LocalProxy

_internal = None

def init_value():
    global _internal
    _internal = "I'm ready now!"

proxy = LocalProxy(lambda: _internal)
# main.py
from external_module import _internal, proxy, init_value

print(_internal)   # None
print(proxy)       # None
init_value()
print(proxy)       # I'm ready now!
print(_internal)   # None

The lazy-loading aspect isn't covered in the documentation, but LocalProxy does what you're asking for, namely:

  1. Acts as a proxy for another object
  2. Defers evaluation until the object is accessed (as opposed to at import, for instance)
  3. Presents itself as the proxied object (from the documentation):

"__repr__ and __class__ are proxied, so repr(x) and isinstance(x, cls) will look like the proxied object. Use issubclass(type(x), LocalProxy) to check if an object is a proxy."

from werkzeug.local import LocalProxy

class Example:
    def __init__(self):
        print("Example initialized")

lazy = LocalProxy(Example)              # Example initialized
print(isinstance(lazy, Example))        # True

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.