如何以编程方式创建python装饰器

时间:2014-08-08 20:10:37

标签: python decorator python-decorators

我正在编写一个创建/提供各种Python装饰器的应用程序。我希望这个应用程序能够进行本地化,包括装饰者的名字。装饰器最终将被其他使用我的应用程序作为框架的开发人员使用(将我的应用程序视为测试框架)。

理想情况下,我希望能够根据本地化设置动态创建装饰器。

例如,如果选择的语言是英语,我希望我的装饰者被命名为#34; apple",如果它是法语,我会喜欢它被命名为#34; pomme"。

在Python代码中,它看起来像:

@apple
def my_func():
    pass

@pomme
def my_func():
    pass

我最终希望能够灵活地添加更多语言,而无需修改或复制大量代码。理想情况下,我只有一个装饰器功能可以处理" apple"或者" pomme"取决于设置。

实现这一目标的最佳途径是什么?

1 个答案:

答案 0 :(得分:0)

首先,不要这样做。这将给您带来许多问题,让您和您的用户的生活更加艰难。无论如何,python是非常动态的,所以你可以这样做。

像这样设置你的包:

yourpackage/
    __init__.py
    decorators.py

decorators.py

# List all decorators you want to publish. Use english names here.
__all__ = ['apple', 'orange', ...]

# Here come implementations named in english
def apple(...):
    ...

...

__init__.py

# Whatever over submodules export or just []
__all__ = [...]

from . import decorators

# Get locale somehow
LOCALE = ...

# This translation function could be as complex as you wish
# I use a lookup in hard-coded dict
TRANSLATIONS = {
    'fr': {'apple': u'pomme', ...},
    ...
}
def _translate_name(name):
    # If something is not translated we use default english name,
    # could be easily changed to raise error
    return TRANSLATIONS.get(LOCALE, {}).get(name, name)

# Generate dynamic attributes to current module and add them to __all__
import sys
this_module = sys.modules[__name__]

for name in decorators.__all__:
    translated = _translate_name(name)
    setattr(this_module, translated, getattr(decorators, name))
    __all__.append(translated)

__all__中管理__init__.py是可选的。这是为了from yourmodule import *