处理超载的最“Pythonic”方式

免责声明:这可能是一个非常主观的问题,没有“正确”的答案,但我很欣赏有关最佳实践和程序设计的任何反馈.所以这里:

我正在编写一个库,其中文本文件被读入Text对象.现在可以使用文件名列表或直接使用Sentence对象列表初始化这些文件.我想知道最好/最Pythonic的方法是什么,因为,如果我理解正确,Python不直接支持方法重载.

我在Scikit-Learn的feature extraction module中找到的一个例子只是在初始化对象时将输入的类型作为参数传递.我假设一旦设置了这个参数,它只是在内部处理不同的情况:

if input == 'filename':
    # glob and read files
elif input == 'content':
    # do something else

虽然这很容易实现,但它看起来不是一个非常优雅的解决方案.所以我想知道是否有更好的方法来处理多种类型的输入来初始化我忽略的类.

解决方法:

一种方法是只为不同的实例化对象的方法创建具有不同名称的类方法:

class Text(object):
    def __init__(self, data):
        # handle data in whatever "basic" form you need

    @classmethod
    def fromFiles(cls, files):
        # process list of filenames into the form that `__init__` needs
        return cls(processed_data)

    @classmethod
    def fromSentences(cls, sentences):
        # process list of Sentence objects into the form that `__init__` needs
        return cls(processed_data)

这样,您只需创建一个“真实”或“规范”初始化方法,该方法接受您想要的任何“最小公分母”格式.专门的fromXXX方法可以预处理不同类型的输入,将它们转换为需要传递给规范实例化的形式.这个想法是你调用Text.fromFiles(…)从文件名中创建Text,或者调用Text.fromSentences(…)从句子对象中创建Text.

如果您只想接受几种可输入类型的输入中的一种,那么进行一些简单的类型检查也是可以接受的.例如,类接受文件名(作为字符串)或文件对象的情况并不少见.在这种情况下,你会做:

def __init__(self, file):
    if isinstance(file, basestring):
        # If a string filename was passed in, open the file before proceeding
        file = open(file)
    # Now you can handle file as a file object

如果要处理许多不同类型的输入,这会变得难以处理,但如果它是相对包含的东西(例如,一个对象或可用于获取该对象的字符串“name”),它可能比第一个更简单我展示的方法.

上一篇:Java中的上传问题?


下一篇:java – RTS游戏中对象的多态性和类层次结构问题