我为一个可能是基本问题的问题道歉。我是一名C++程序员,对python比较陌生。
我有一个python类,它的行为很大程度上依赖于它的一个构造函数参数:
class MyClass():
def __init__(self, some_arg):
self.some_arg = some_arg
...
def abcd(self):
if self.some_arg == 1:
...
else:
...
def efgh(self):
if self.some_arg == 1:
...
else:
...我想将其重构为两个具有不同some_arg值的类。当然,最直接的方法是有两个类(可能有一个公共基类),然后让工厂函数选择实例化哪一个。大致是这样的:
def MyClassSomeArg1():
def __init__(self):
...
def abcd(self):
...
def efgh(self):
...
def MyClassSomeArgNot1():
def __init__(self):
...
def abcd(self):
...
def efgh(self):
...
def buildMyClass(some_arg):
if some_arg == 1:
return MyClassSomeArg1()
else:
return MyClassSomeArgNot1()我相信那会工作得很好。问题是我不想更改客户端代码。客户端期望使用some_arg的构造函数参数实例化"MyClass“类的对象。有没有一种好的方法可以在不改变客户端代码的情况下进行重构呢?
我尝试过使用实现层次结构: MyClassImpl作为基类,带有子类MyClassImplSomeArg1和MyClassImplSomeArgNot1。然后,MyClass本身就变得基本上是空的:
class MyClass():
def __init__(self, some_arg):
if some_arg == 1:
self._impl = MyClassImplSomeArg1()
else:
self._impl = MyClassImplSomeArgNone1()
def __getattr__(self, a):
# For performance, I could store this in self so it doesn't need to be looked up each time
return getattr(self._impl, a)这基本上是可行的,但似乎不是最直接的事情。首先,像__str__和__eq__这样的神奇方法似乎没有通过__getattr__机制进行委托,我不知道为什么。不过,我自己编写委托方法并不难。此外,这会使pydoc感到困惑(它无法看到委托的属性),我不确定如何解决这个问题。
有没有一些糖可以让这个授权方案很好地发挥作用?或者委派是处理这样的问题的最佳方式吗?
谢谢,
发布于 2020-04-21 02:41:40
您可以覆盖__new__函数并返回一个基于some_arg的子类。这是实现工厂的常见模式
class MyClassImplSomeArg1:
pass
class MyClassImplSomeArgNone1:
pass
class MyClass:
def __new__(cls, some_arg):
if some_arg:
return MyClassImplSomeArg1()
else:
return MyClassImplSomeArgNone1()
assert isinstance(MyClass(some_arg=True), (MyClassImplSomeArg1,))
assert isinstance(MyClass(some_arg=False), (MyClassImplSomeArgNone1,))https://stackoverflow.com/questions/61329394
复制相似问题