惰性加载/配置一个类以继承
我创建了一个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”的方法来解决这个问题呢?比如说使用动态继承或者懒加载,或者其他什么方法……?
3 个回答
0
看起来你想根据 use_option
给 ExampleClass
添加一些额外的功能。我建议你写两个类(一个是从另一个类派生出来的,增加了额外的功能),然后根据 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
里面了。
(也许这就是 millimoose 提到的策略模式;我也不太确定。)
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
里。(具体怎么做还不太确定,因为不清楚这个可能继承的类是怎么使用的。)
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')
。