英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论