延迟加载/配置要继承的类

时间:2013-02-14 16:16:50

标签: python python-2.7 lazy-loading multiple-inheritance

我创建了一个带有可选部件/类的Python包。当我使用这个可选部分(OptClass)时,我必须更改类的继承(ExampleClass)。现在我使用这段代码:

if use_option :
    _opt_class =  __import__('package.my_module', globals(), locals(), ['OptClass']).OptClass
else :
    _opt_class = object # do not use the optional class

....

class ExampleClass(base_module.BaseHandler, _opt_class):

    ....

还有另一种Pythonic解决方法吗?例如,使用动态继承或layzy加载,或者......?

3 个答案:

答案 0 :(得分:1)

我可能会使用类装饰器:

def optional_inherit(cls):
    if use_option:
        from package.my_module import OptClass
        class ExampleClassWithOptClass(cls, OptClass):
            pass
        return ExampleClassWithOptClass
    else:
        return cls

...

@optional_inherit
class ExampleClass(base_module.BaseHandler):
    ...

如果你这么做很多,你可以写optional_inherit来论证;在这种情况下,@optional_inherit(use_option, 'package.mymodule.OptClass')

答案 1 :(得分:0)

您希望根据ExampleClassuse_option添加一些额外的行为。我只想编写两个类(一个派生自另一个类,添加了额外的行为),然后使用通用名称指向其中一个类,具体取决于use_option

from package.my_module import OptClass

class SimpleExampleClass(base_module.BaseHandler):
    pass

class ExtendedExampleClass(SimpleExampleClass, OptClass):
    pass

ExampleClass = ExtendedExampleClass if use_option else SimpleExampleClass

这样,您甚至无需在ExtendedExampleClass中添加额外的功能:它已全部在OptClass

(也许这就是提到的战略模式;我真的不知道。)

答案 2 :(得分:0)

我会考虑明确地对这种模块化进行建模。你提到了OAuth2,所以为了这个例子,我假设你要添加的功能是使用该协议的身份验证。

然后你会有以下文件:

authmodule.py

import oauth2client
# ...

class OAuth2Module(object):
    # ...

exampleclass.py

class ExampleClass(base_module.BaseHandler):
    def __init__(self, auth_module, ...):
        self.auth_module = auth_module
        # ...

    def foo(self):
        if self.auth_module:
            self.auth_module.bar()

main.py

# this is where ExampleClass is created
if use_option:
    # the optional dependency only really gets pulled in here
    from authmodule import AuthModule
    example_obj = ExampleClass(AuthModule())
else:
    example_obj = ExampleClass(None)

# ...
example_obj.foo()

显然,这可以稍微不同地实现,例如将样板从ExampleClass移动到DummyAuthModule。 (当然不能确定如何使用可能继承的类。)