英文:
Refactoring a class method to be under an abstract base class and splitting the logic without changing the base class method signature?
问题
我目前正在重新设计一个类,将其置于一个抽象基类之下。当前类具有一个名为 func
的方法,该方法执行一些与两个事物 A
和 B
相关的逻辑。
在逻辑 A
过程中,它将一个大型数据集加载到一个字典中,比如 dataset
,然后稍后在逻辑 B
中使用 dataset.keys()
,但除此之外,A
和 B
是彼此独立的。
我将创建一个另一个类,比如 another_class
,它类似于 current_class
,但这个类不需要 B
,只需要 A
。所以类似这样:
class another_class:
def func(self):
# 对A执行一些操作
然后,两者都将置于一个抽象基类 base
之下。由于两个继承的类都涉及到 A
,我打算在基类中创建一个执行 A
的方法,比如 func_A
。但我在想如何最好地处理这个问题,以使函数签名一致,同时避免为 B
重新加载 dataset
。
如果 another_class
也需要 B
的逻辑,我认为我们可以从 func_A
中返回 dataset.keys()
,然后在 func_B
中使用它,但 another_class
不需要。
因此,我不知道是否有一种好的方法来使这一点一致,而不必为这些方法使用不同的签名。
所以在代码中,我有以下两个想法:
1)
class base:
@abstractmethod
def func(self):
pass
def func_A(self):
# 对A执行一些操作并获取数据集
return dataset.keys()
class current_class:
def func_B(self, keys):
# 对B执行一些操作
def func(self):
keys = self.func_A
self.func_B(keys)
class current_class:
def func(self):
_ = self.func_A() # 返回值未被使用...
2)
class base:
@abstractmethod
def func(self):
pass
class current_class:
def func_A(self):
# 对A执行一些操作并获取数据集
return dataset.keys()
def func_B(self, keys):
# 对B执行一些操作
def func(self):
keys = self.func_A()
self.func_B(keys)
class current_class:
def func_A(self):
# 对当前类执行与func_A相同的操作,并且不返回任何内容
def func(self):
self.func_A()
我不喜欢第一种设计,因为 func_A
只需要为其中一个子类返回值,而不需要为所有子类返回值。我也不喜欢第二种设计,因为我们必须在每个继承的类中分别实现 func_A
,尽管它们是相同的方法,只是一个需要返回值,而另一个不需要。
英文:
I'm currently working on redesigning a class to be under an abstract base class. The current class has a method func
that does some logic for two things, say A
and B
.
(note that all the code below is very simplified. There's a lot more functionality than what is shown)
class current_class:
def func(self):
# does stuff for A
# does stuff for B
During logic A
, it loads a large dataset into a dictionary, say, dataset
and later dataset.keys()
is used for logic B
, but other than that, A
and B
are independent of each other.
I will create an alternate class, say, another_class
that is similar to current_class
, but this class doesn't need B
and only needs A
. So something like
class another_class:
def func(self):
# does stuff for A
And then both will be under an abstract base class base
. Since both inherited classes involves A
, I plan on just creating a method in base class that does A
, say, func_A
. But I'm having trouble with figuring out the best way to approach this so that the function signatures conform and without having to reload dataset
for B
.
If another_class
also needed the logic for B
, I think we can just return dataset.keys()
from func_A
and use it in func_B
, but another_class
doesn't.
So I don't know if there's a good way to conform this without having different signatures for the methods.
So in code, I have the following two ideas:
1)
class base:
@abstractmethod
def func(self):
pass
def func_A(self):
# does stuff for A and gets the dataset
return dataset.keys()
class current_class:
def func_B(self, keys):
# does stuff for B
def func(self):
keys = self.func_A
self.func_B(keys)
class current_class:
def func(self):
_ = self.func_A() # the return is unused...
2)
class base:
@abstractmethod
def func(self):
pass
class current_class:
def func_A(self):
# does stuff for A and gets the dataset
return dataset.keys()
def func_B(self, keys):
# does stuff for B
def func(self):
keys = self.func_A()
self.func_B(keys)
class current_class:
def func_A(self):
# does same stuff as func_A for current_class, and doesn't return anything
def func(self):
self.func_A()
I don't like the first design because func_A
only needs to return something for one of the subclasses and not for all of them. I also don't like the second design because we have to separately implement func_A
in each inherited class even though they're identical methods, except one needs to return something and the other doesn't.
答案1
得分: 1
不必担心忽略主要用于其副作用的函数的返回值。只需在基类中定义func_A
一次,然后让两个子类根据其需求适当使用它。
class Base:
@abstractmethod
def func(self):
pass
def func_A(self):
# 为A执行操作并获取数据集
return dataset.keys()
class Child1:
def func_B(self, keys):
# 为B执行操作
def func(self):
keys = self.func_A
self.func_B(keys)
class Child2:
def func(self):
self.func_A()
如果func_A
中有与Child2
无关的内容,那么当然应将其拆分,以避免在Child2.func
中执行不必要的工作。但仅仅返回一个值既不会占用太多时间,也不会占用太多空间,不应成为担忧。
英文:
It's not a big deal to ignore the return value of a function that is primarily called for its side effects. Just define func_A
once in the base class and let both child classes use it as appropriate to their needs.
class Base:
@abstractmethod
def func(self):
pass
def func_A(self):
# does stuff for A and gets the dataset
return dataset.keys()
class Child1:
def func_B(self, keys):
# does stuff for B
def func(self):
keys = self.func_A
self.func_B(keys)
class Child2:
def func(self):
self.func_A()
If there is more in func_A
that isn't necessary for Child2
, then it should of course be split up to avoid doing unnecessary work in Child2.func
. But simply returning a value is not in anyway time- or space-intensive, and should not be a concern.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论