Comments (7)
funcy already has LazyObject doesn't it work for you? If not can you please explain the specifics?
from funcy.
Hi @Suor , yes I use it a bunch for initialization too. The pattern I'm describing is something along the lines of:
foo_api = Proxy()
foo_api_1 = FooApi()
foo_api.initialize(foo_api_1)
foo_api.bar() # uses foo_api_1
foo_api_2 = FooApi()
foo_api.initialize(foo_api_2)
foo_api.bar() # uses foo_api_2
I find this pattern useful for testing and abstracting connections to db's and stuff.
This cannot be accomplished with the LazyObject
since _setup cannot be called for an adhoc object (same as with other libraries mentioned before). This is not much of a "Lazy" pattern but a "deferred" initialization one I believe.
Thanks. Luis
from funcy.
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 LazyObject
itself somehow, i.e. by allowing ._setup()
to accept arguments or smth. Or simply subclassing it, rewriting how initialization is done.
from funcy.
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 obj
has a class with slots though, same as LazyObject
.
from funcy.
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:
class Foo():
def bar(self):
print(id(self))
p = DeferInitObject()
p.init(Foo())
p.bar()
p.init(Foo())
p.bar()
on the second init it will raise AttributeError: 'Foo' object has no attribute 'init'
where as with the make_proxy:
p, p_init = make_proxy()
p_init(Foo())
p.bar()
p_init(Foo())
p.bar()
will print same id, i.e.:
$ python foo.py
140142395670336
140142395670336
effectively not using the second init.
Just as an example:
from peewee import Proxy
p = Proxy()
p.initialize(Foo())
p.bar()
p.initialize(Foo())
p.bar()
gives:
$ python foo.py
140282243186400
140282243186352
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
from funcy.
Ok, I see, I missed that you rewrite the object twice. The name initialize
also didn't help. I guess one may get rewiring code out and make it work like:
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 peewee.Proxy
code to your project and use it. Or do something in-between.
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.
from funcy.
Hi @Suor,
Never realized how easy it to do this with this rewiring snippet you gave.
Thanks :)
from funcy.
Related Issues (20)
- Feature request: Support method chaining HOT 14
- Add `del_in()` to colls.py for symmetry and completeness HOT 3
- Add type stubs HOT 23
- rcurry and similar functions do not work with methods of built-in types HOT 7
- Apply a list object to a function's argument-list HOT 2
- Retry infinity HOT 2
- funcy.autocurry doesn't work with functions with key-words only HOT 4
- `join_with` - transform single elements too HOT 10
- In the cheatsheet area, the function nth signature does not include a parameter n.
- Dict deep merge? HOT 1
- Unprecise documentation on extended function semantics HOT 1
- Add the "strict" kwarg to lzip HOT 2
- Support Python 3.11 HOT 1
- Flow function `retry` as non-decorator variant HOT 2
- Feature request: function to strip arguments from function call HOT 1
- Support Python 3.12 HOT 2
- Feature Request: async versions of functions? HOT 1
- Map splat: treat each element as keyword arguments to be passed to the input function HOT 1
- Essays are offline HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from funcy.