假设我有一个包含两个模块moduleA
和moduleB
的软件包。两者都应提供两个字符串操作函数作为接口manipulate
和undo_manipulation
,但是它们的操作细节应有所不同。
比方说,我希望manipulate
的{{1}}用moduleA
替换"i"
的所有实例,将第一个字母移到末尾,然后大写第一个字母:
"u"
另一方面,在>>>moduleA.manipulate("string")
'Trungs'
中,应将moduleB
替换为"r"
,将第一个字母移到末尾,然后交换新的第一和第二个字母,然后大写:>
"w"
例如,我将>>>moduleB.manipulate("string")
'Wtings'
实现为:
moduleA
(为简单起见,我假设输入总是至少3个字符)
现在我想为to_replace = {"i": "u"}
def manipulate(string):
for key, value in to_replace.items():
string = string.replace(key, value)
string = move_letter(string)
return capitalise(string)
def move_letter(string):
return string[1:]+string[0]
def capitalise(string):
return string[0].upper()+string[1:]
做的是让它只是“继承”整个moduleB
然后覆盖细节(即,定义一个新的moduleA
和{{1 }})。然后,用户应该能够调用to_replaced
,并且它将调用导入的函数,然后才使用更新的上下文。所以基本上:
move_letter
(显然,我实际上想要执行的操作要复杂一些;但是它们也可以分解为更多的原子部分,其中只有一些应该被“子”模块覆盖)
很遗憾,这不起作用。如果用户呼叫moduleB.manipulate
,它将使用from moduleA import manipulate, move_letter, capitalise
# second import necessary if I want to access the original version of move_letter
from . import moduleA
to_replace{"r": "w"}
def move_letter(string):
newstring = moduleA.move_letter(string)
return newstring[1]+newstring[0]+newstring[2:]
和moduleB.manipulate
的{{1}}版本,而不是moduleA
的更新版本。
有什么办法解决吗?换句话说,是否有一种方法可以仅使用模块来模拟对象继承,而无需使用类?
我知道我想要的行为可以使用对象继承轻松实现,但是从接口和编码的角度来看,在这里使用对象都不适合,因为:
to_replace
和move_letter
)都感觉比“名词-y”更“动词-y”。moduleB
(至少除非他们这样做manipulate
,否则,如果要使用两个以上或三个以上的独立模块,则也会很麻烦导入)。由于这些原因,我真的很想避免使用类。否则,我至少会找到某种方法从界面隐藏类层,以节省用户输入的时间。