python - How to make arguments in python decorator configurable?
问题描述
I am using cachetools for some basic caching. Here is an example of how I am using it:
class Access:
@cached(cache=TTLCache(maxsize=5, ttl=10))
def get_some_value(input: str):
# do some calls and return a value
The problem here is how do I make the maxsize
and ttl
configurable? I cannot do something like
class Access:
def __init__(self, maxsize: int = 5, ttl: int = 10):
self.maxsize = maxsize
self.ttl = ttl
@cached(cache=TTLCache(maxsize=self.maxsize, ttl=self.ttl))
def get_some_value(input: str):
# do some calls and return a value
I am looking for a way to inject those values if required and also have a default. Any helpful pointers?
Also, get_some_value()
need not be an instance method. I could just make it a class method or module level also if need be.
解决方案
To deal with this, we can use the fact that Python decorators are simply functions that return other functions.
Suppose you have this eggs
decorator:
def eggs(foo=10, bar=20):
def wrapper_gen(func):
def wrapper(*args):
print(foo, bar)
func(*args)
return wrapper
return wrapper_gen
And this Spam
class:
class Spam:
@eggs(foo=10, bar=20)
def baz(self, input):
print(input)
We can call the baz
method as such:
Spam().baz("Hello, world!")
And this gives us
10 20
Hello, world!
Now, instead of directly decorating the function, we'll decorate in our __init__
method:
class Spam:
def __init__(self, foo=10, bar=20):
self.baz = eggs(foo=foo, bar=bar)(self._baz_func)
def _baz_func(self, input):
print(input)
And now:
Spam(foo=20, bar=30).baz("Hello, world!")
This outputs
20 30
Hello, world!
The reason this works is that this:
@foo
def bar():
...
is shorthand for this:
def bar():
...
bar = foo(bar)
推荐阅读
- openssl - 使用 openssl 库交叉编译到 arm
- swift - 如何在 swiftyJSON 和 Alamofire 中获取字典的随机值
- bash - 在bash中反转布尔输出的单线方法?
- ruby-on-rails - 如何扩展 activejob-google_cloud_pubsub 工作人员?
- excel - Excel公式_匹配
- ios - Flutter firebase google-sign-in a pop in iOS 未显示我已建立的 Google 帐户
- node.js - Discord.js - 如何编辑机器人命令确认消息
- javascript - 由于我故意制造的无限循环,我的 javascript 代码无法正常工作
- laravel - Laravel 6.12“尚未设置外观根。” 使用日志时::
- authentication - 由于范围无效,Identity Server 4 请求验证失败