如何考虑 Python 中代码可重用性和可扩展性的 OOP 设计选择?

Posted

技术标签:

【中文标题】如何考虑 Python 中代码可重用性和可扩展性的 OOP 设计选择?【英文标题】:How to think about OOP design choices for code re-usability and extensibility in Python? 【发布时间】:2021-05-30 10:06:38 【问题描述】:

上下文:

我有OneHotEncoder 对象的这个组合(对我来说是新词汇):

class CharEncoder:

    characters = cn.ALL_LETTERS_ARRAY

    def __init__(self):
        self.encoder = OneHotEncoder(sparse=False).fit(self.characters.reshape(-1, 1))
        self.categories = self.encoder.categories_[0].tolist()

    def transform(self, word):
        word = np.array(list(word)).reshape(-1, 1)
        word_vect = self.encoder.transform(word)
        return word_vect

    def inverse_transform(self, X):
        word_arr = self.encoder.inverse_transform(X).reshape(-1,)
        return ''.join(word_arr)

如您所见,它有一个类属性characters,它本质上是一个由所有 ASCII 字符加上一些标点符号组成的数组。

我想让这个CharEncoder 类不仅仅对 ASCII 有用。也许其他人真的想使用不同的字符集,我想允许他们这样做。或者他们可能想对整个单词而不是单个字母进行编码......谁知道呢!?

我的问题:

我觉得这里有很多设计选择可以使这段代码可重用于稍有不同的任务。我感到不知所措。

    我将字符集设为类属性还是实例属性? 我是否为字符集编写 getter 和 setter? 我是否改为为不同的字符集编写一些父类和子类。 还是让用户将他们自己的 OneHotEncoder 对象传递给我的类,而不用自己操心?

我的问题:

有哪些注意事项可能有助于指导我的设计选择?

【问题讨论】:

据我所知,这里唯一的“可配置”元素是characters,对吗? @DeepSpace 是的,当然。而且这种配置会产生如此多的设计选择问题,哈哈。进一步的上下文是我有另一个类,其中一个属性是CharEncoder 实例。这让一切变得更加复杂! 【参考方案1】:

我只是将characters 设为具有默认值的实例属性。

class CharEncoder:
    def __init__(self, characters=cn.ALL_LETTERS_ARRAY):
        self.characters = characters
        self.encoder = OneHotEncoder(sparse=False).fit(self.characters.reshape(-1, 1))
        self.categories = self.encoder.categories_[0].tolist()

Caution: If cn.ALL_LETTERS_ARRAY is mutable (ie a Python list or a numpy array), use None as a sentinel value:

def __init__(self, characters=None):
    self.characters = characters or cn.ALL_LETTERS_ARRAY
    # a shorter version for
    # if characters is None:
    #   self.characters = cn.ALL_LETTERS_ARRAY
    # else:
    #   self.characters = characters
    # with a small caveat that self.characters can't be set to
    # an empty string/list/array/dict because these evaluate to False

用法:

default_chars_encoder = CharEncoder() # using the default cn.ALL_LETTERS_ARRAY 
custom_chars_encoder = CharEncoder(CUSTOM_CHARCTERS_SET) # using CUSTOM_CHARCTERS_SET

【讨论】:

以上是关于如何考虑 Python 中代码可重用性和可扩展性的 OOP 设计选择?的主要内容,如果未能解决你的问题,请参考以下文章

面向对象与面向过程

在运行时与构建时如何保护云计算基础设施

如何测量python中代码行之间的时间?

资源的调度——线程池

服务治理那些事-容错之断路器

第5章:函数式编程