我创建的每个业务规则都会放在名为“rule_definitions。”的文件夹中。
我有一个班级Rule
。它充当所有这些创建规则的模板,它们可以从中继承必要的通用函数。
文件夹内容的一个示例:
rule_definitions/
discard.py
saveValue.py
storeValue.py
writeToOutput.py
但是如果你想创建一个规则的实例,那么就可以了:
rule = Rule('discard')
并让Rule
类进行导入,而不是每次需要加载规则时都找到适当的规则模块。
例如,rule_definitions.py
的内容可能是:
from Rule import Rule
class _discard(Rule):
...
在Rule
内,我们可能会:
import importlib
class Rule():
"""A template class that all rules inherit from and are instantiated from."""
def __init__(self, rule):
# load the rule by name from rule definitions
try:
self.Rule = importlib.import_module('defs._'+ rule)
except ImportError:
print 'Failed to find rule definiton while attempting to load
#other generic functions to inherit below
这是最干净的方式吗?我不确定这是不是标准做法。
答案 0 :(得分:1)
您正在执行的操作与动态加载数据库迁移类似。 Django和类似的数据库相关项目可能包含您可以查看的代码。
我写了一些自动加载和导入的代码。
看看我在这里写的load_migrations
函数https://github.com/someones/exodus/blob/master/exodus/init.py
核心Exodus类从指定目录加载迁移。
每个文件都有一个扩展BaseMigration对象的类。
BaseMigration的元类将在解析时注册一个中心迁移列表。
答案 1 :(得分:1)
这里有一些问题。让我一个接一个地做:
您提出的建议并不需要_discard
继承Rule
。你正在使用继承和组合,这看起来令人困惑。
您返回的规则仍然是Rule
类型,而不是_discard
。也许这就是你想要的,也许不是......
Rule('discard')
无法进行静态检查,也无法获得您期望的自动完成功能(如果您使用的是IDE)。
以下是一些改进建议:
Rule
继承。要么使用另一个类作为通用功能,要么将父项传递给_discard
构造函数。 (第二个会产生参考循环)使用另一个通用功能类,它看起来像这样:
class RuleTrait(object):
def some_common_stuff(self):
...
class _discard(RuleTrait):
def do_work(self):
some_common_stuff()
class Rule(object):
def __init__(self, typ):
self.impl = _get_impl_by_name(typ)
def __getattr__(self, name):
return getattr(self.impl, name)
Rule("discard").do_work() # this will be forwarded to _discard.do_work
实际继承:不要使用泛型构造函数,而是使用直接类。 Rule('discard')
并不比rules.Discard()
差,它会为您提供更好的类型检查。你可以摆脱导入魔法。
如果在某些情况下需要更多导入魔法,请将其改为工厂。 Rule(...)
只能创建一个Rule
对象。但是,您可以使用您需要的任何实现来编写make_rule('discard')
。