我正在编写一个Python库,用作第三方库。
great_library/__init__.py
:
class ClassA(object):
@cache()
def foo(self):
pass
class ClassB(object):
@cache()
def bar(self):
pass
class GreatLibrary(object):
@classmethod
def great_api(cls):
pass
# uses ClassA and ClassB
此库用作:
from great_library import GreatLibrary
GreatLibrary.great_api()
现在的问题是,我希望用户配置缓存过期时间。应该传递给@cache()
:@cache(seconds)
我应该如何设计这个模块结构,以便用户可以轻松传入配置并让它由classA和classB使用?感谢
答案 0 :(得分:1)
基本问题是当加载模块时,将读取传递给装饰器的变量。所以之前没有办法改变它(至少如果你不想通过一些黑客重新加载模块但是不能改变旧的对象)。所以你需要一些钩子,其中great_library
可以获得缓存时间的值以及用户可以写出所需值的位置。
更简单和广泛使用的方法是设置环境变量。在great_library
模块的顶部,您可以检查变量并加载默认缓存时间:
import os
default_time = os.getenv("GREAT_LIBRARY_CACHE_TIME", None)
在您的代码中使用@cache(default_time)
。我不确定cache()
API会将None
作为默认参数,否则很容易修改收据以使其适应您的问题。
现在,great_library
的用户可以在开发阶段(导入模块之前)通过os.putenv()
或通过生产中的OS环境进行设置。
另一种放置挂钩的方法是使用配置模块导入。恕我直言,只有当你要设置一堆属性时,该方法才有用。如果您遵循该路径,则great_library
模块应实现以下内容:
try:
from great_library_config import *
except ImportError:
# Default configurations like...
default_time = None
我个人试图避免模块的解决方案,但对于具有高度可配置性的应用程序或框架非常有用。无论如何,在这种情况下,用户可以使用配置模块进行生产,并通过开发/测试来覆盖它。