-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: Proxy Object #129
Comments
funcy already has LazyObject doesn't it work for you? If not can you please explain the specifics? |
Hi @Suor , yes I use it a bunch for initialization too. The pattern I'm describing is something along the lines of:
I find this pattern useful for testing and abstracting connections to db's and stuff. This cannot be accomplished with the Thanks. Luis |
And how you want it to look? The same way it's in your code then that could be achieved with something like: def make_proxy():
obj = None
@LazyObject
def proxy():
if obj is None:
raise ValueError("You need to init the proxy before using it")
return obj
def init(api):
nonlocal obj
obj = api
return proxy, init And use it like: foo_api, init_foo_api = make_proxy()
init_foo_api(FooApi())
foo_api.bar() It could also be integrated into |
The full thing could be written as: class DeferInitObject:
def init(self, obj):
object.__setattr__(self, '__class__', obj.__class__)
object.__setattr__(self, '__dict__', obj.__dict__)
def __getattr__(self, name):
raise ValueError("You need to init the proxy before using it")
def __setattr__(self, name, value):
raise ValueError("You need to init the proxy before using it") Won't work when |
Hi @Suor, Thank you very much for your replies. In the examples you gave the proxy object can only be initialized once and not multiple times like in the example I gave. Example:
on the second init it will raise where as with the make_proxy:
will print same id, i.e.:
effectively not using the second init. Just as an example:
gives:
Again, when I'm using peewee I use the Proxy that comes with it, but when no sql db is needed and I don't have peewee installed I find it silly to include a sql db library just to apply this pattern. Since funcy is always the first in the list :) and this is akin to its sort of utilities, I was wondering if there is an opening to include it. Thanks, Luis |
Ok, I see, I missed that you rewrite the object twice. The name def rewire(dest, source):
object.__setattr__(dest, '__class__', source.__class__)
object.__setattr__(dest, '__dict__', source.__dict__)
foo_api = object()
foo_api_1 = FooApi()
rewire(foo_api, foo_api_1)
foo_api.bar() # uses foo_api_1
foo_api_2 = FooApi()
rewire(foo_api, foo_api_2)
foo_api.bar() # uses foo_api_2 Or you can simply copy this It might be useful to have it in funcy in some form, not sure which one exactly though. Also, making it explicit instead of implicit is also an option if you control the using part of your code: foo_api = Proxy()
foo_api.client = FooApi()
foo_api.client.bar() # uses foo_api_1
foo_api_2 = FooApi()
foo_api.client = foo_api_2
foo_api.client.bar() # uses foo_api_2 This might be easier on the code reader in the future. |
Hi @Suor, Never realized how easy it to do this with this rewiring snippet you gave. Thanks :) |
Add a Proxy object in style of peewee.Proxy in order to have a later initialization of the object. There are some libraries (wrapt or lazy-object-proxy) but they don't cover this specific scenario where initialization occurs after proxy is initialized. If there is interest I can go on and make a pr. Thanks for awesome library.
The text was updated successfully, but these errors were encountered: