2

我创建了一个带有可选部分/类的 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 方法来解决这个问题?例如使用动态继承或延迟加载,或者......?

4

3 回答 3

2

我可能会使用类装饰器:

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')

于 2013-02-14T17:37:13.753 回答
0

I'd consider modeling this modularity explicitly. You mention OAuth2, so for the sake of the example I'll assume the functionality you want to add is authentication using that protocol.

Then you'd have files like:

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()

Obviously this can be implemented a little differently, like moving the boilerplate from ExampleClass into a DummyAuthModule. (Can't really tell for sure seeing as it's not certain how the maybe-inherited class is used.)

于 2013-02-14T17:56:52.780 回答
0

看起来你想添加一些额外的行为到ExampleClassbased on use_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已经全部完成了。

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

于 2013-02-14T17:30:46.333 回答