我创建了一个带有可选部件/类的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加载,或者......?
答案 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)
您希望根据ExampleClass
向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
。
(也许这就是提到的战略模式;我真的不知道。)
答案 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
。 (当然不能确定如何使用可能继承的类。)