如何创建隐藏工厂?

2024-10-02 12:25:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道以前有报道过,但我就是不明白。。。你知道吗

我想创建一个用文件名调用的类,但是根据文件名的扩展名,它会变形为几个子类之一。它认为这是一个工厂模式,我在使用staticmethod之前就已经这样做了,但是我现在正在尝试,不完全是为了好玩,用一个基类的公共实例化来实现它。这可能吗?你知道吗

 >>> foo = FileClass('foo.txt')
 >>> type(foo)
 <type 'TextFileClass'>

 >>> foo = FileClass('foo.rtf')
 >>> type(foo)
 <type 'RTFFileClass'>

这不是实际产出,而是我希望达到的目标。我一直在尝试疯狂的东西,一定是偏离了轨道。目前,我已经在FileClass中实现了一个__new__例程,但似乎不对。似乎有很多方法可以做到这一点?什么是正确的?你知道吗


Tags: 实例txtfoo文件名工厂type模式基类
3条回答

如果FileClass不能是工厂函数,则可以应用Handle/Body模式(或派生的Envelope/Letter模式)使FileClass实例化实现类,将其保存在字段中并对其进行代理方法调用。使用者不会看到变量类型中的子类,但接口会出现,这一点很重要。你知道吗

使用__new__执行此操作的主要问题是,如果FileClass.__new__调用TextFileClass构造函数,TextFileClass如何启动实例以返回?你知道吗

为了解决这个问题,我们可以测试cls__new__中是什么,这样我们就不会干扰子类__new__

def __new__(cls, filename):
    if cls is FileClass:
        return cls._factory(filename)
    return super(FileClass, cls).__new__(cls, filename)

调用FileClass('foo.txt')时,如果对象是FileClass的实例,Python将对从__new__返回的对象调用__init__,因此我们必须使用TextFileClass.__new__('foo.txt')而不是TextFileClass('foo.txt')

@classmethod
def _factory(cls, filename):
    if filename.endswith('.txt'):
        return TextFileClass.__new__(filename)
    elif filename.endswith('.rtf'):
        return RTFFileClass.__new__(filename)
    ...

总之,这样做可能不值得。工厂函数或工厂方法更容易获得正确的结果。你知道吗

为什么不直接使用工厂函数呢?你知道吗

class BaseFile(object):
    """Inherit these common methods and properties"""
    def __init__(self, fname):
        self.fname = fname

    def is_pretty(self):
        NotImplemented

class TextFileClass(BaseFile): 
    def is_pretty(self):
        return False

class RTFFileClass(BaseFile):
    def is_pretty(self):
        return True

def createFileClass(fname):
    if fname.endswith('.txt'):
        return TextFileClass(fname)
    elif fname.endswith('.rtf'):
        return RTFFileClass(fname)
    else:
        raise Exception, 'unknown file format'

FileClass = createFileClass

产生:

>>> foo = FileClass('foo.txt')
>>> type(foo)
<class '__main__.TextFileClass'>

>>> foo = FileClass('foo.rtf')
>>> type(foo)
<class '__main__.RTFFileClass'>

相关问题 更多 >

    热门问题