Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 创建预定义类的元类与继承_Python_Python 2.7_Inheritance_Metaclass - Fatal编程技术网

Python 创建预定义类的元类与继承

Python 创建预定义类的元类与继承,python,python-2.7,inheritance,metaclass,Python,Python 2.7,Inheritance,Metaclass,我正在为一个程序编写一些代码,这个程序将能够运行一些软件,读取输入/输出,并在此过程中进行一些数据处理。例如:(这不是真实的情况,只是给出一个想法) 类音乐文件(对象): 扩展名=[“”] def设置(自): #设置数据 def运行软件(自我): #播放歌曲 MP3类(音乐文件): 扩展名=[“.mp3”] def设置(自): #setupMP3file def运行软件(自我): #Runmp3软件 我有大约4个常规类,然后文件扩展名的定义和处理将有所不同。每个类都有一个定义数量的方法,这些方

我正在为一个程序编写一些代码,这个程序将能够运行一些软件,读取输入/输出,并在此过程中进行一些数据处理。例如:(这不是真实的情况,只是给出一个想法)

类音乐文件(对象):
扩展名=[“”]
def设置(自):
#设置数据
def运行软件(自我):
#播放歌曲
MP3类(音乐文件):
扩展名=[“.mp3”]
def设置(自):
#setupMP3file
def运行软件(自我):
#Runmp3软件
我有大约4个常规类,然后文件扩展名的定义和处理将有所不同。每个类都有一个定义数量的方法,这些方法是它工作所必需的。目前,只支持一个或两个文件扩展名,但我想保留一个结构,在这个结构中,添加更多扩展名对其他人来说很容易(也许是直观的)

我编写代码的时间不长,我被赋予了这个任务,我希望以最好的方式完成这个任务

元类的使用是否适合这种情况?为了设置一些严格的类,这些类必须包含我之前定义的方法,这样所有这些方法都是统一的。我应该坚持简单的继承吗

我希望能够注册
MusicFile
的所有子类,以便能够实例化正确的子类(例如,给定文件路径)

我读过关于元类的书,它们似乎很适合这个案例,但因为我也读过,如果你不太了解它们,就不需要使用它们,我想征求你的专家意见

我希望能够注册MusicFile的所有子类,以便能够实例化正确的子类(例如,给定文件路径)

那么您可能想要实现

这个工厂可能是用元类自动构建的。我看到的一个严重问题是使用类自己的
扩展
成员注册它,因此对我来说,元类的永恒竞争更容易实现,装饰者:

class MusicFile(object):
    known_types = {}

    @staticmethod
    def processor(ext):
        return MusicFile.known_types[ext]()

def file_types(*exts):
    def registered_class(cls):
        for ext in exts: MusicFile.known_types[ext] = cls
        return cls
    return registered_class

@file_types('mp3')
class Mp3(MusicFile):
    def greet(self):
        print 'Hi .mp3!'

@file_types('mid', 'midi')
class Midi(MusicFile):
    def greet(self):
        print 'Hi, Music Instruments Digital Interface!'

pcsor = MusicFile.processor('mp3')
pcsor.greet()                      # Hi .mp3!
pcsor = MusicFile.processor('mid')
pcsor.greet()                      # Hi, Music Instruments Digital Interface!
pcsor = MusicFile.processor('midi')
pcsor.greet()                      # Hi, Music Instruments Digital Interface!
pcsor = MusicFile.processor('s3m') # KeyError: 's3m'
pcsor.greet()
我希望能够注册MusicFile的所有子类,以便能够实例化正确的子类(例如,给定文件路径)

那么您可能想要实现

这个工厂可能是用元类自动构建的。我看到的一个严重问题是使用类自己的
扩展
成员注册它,因此对我来说,元类的永恒竞争更容易实现,装饰者:

class MusicFile(object):
    known_types = {}

    @staticmethod
    def processor(ext):
        return MusicFile.known_types[ext]()

def file_types(*exts):
    def registered_class(cls):
        for ext in exts: MusicFile.known_types[ext] = cls
        return cls
    return registered_class

@file_types('mp3')
class Mp3(MusicFile):
    def greet(self):
        print 'Hi .mp3!'

@file_types('mid', 'midi')
class Midi(MusicFile):
    def greet(self):
        print 'Hi, Music Instruments Digital Interface!'

pcsor = MusicFile.processor('mp3')
pcsor.greet()                      # Hi .mp3!
pcsor = MusicFile.processor('mid')
pcsor.greet()                      # Hi, Music Instruments Digital Interface!
pcsor = MusicFile.processor('midi')
pcsor.greet()                      # Hi, Music Instruments Digital Interface!
pcsor = MusicFile.processor('s3m') # KeyError: 's3m'
pcsor.greet()

这个答案只适用于Python3.6+。如果您可以选择升级到最新的Python版本,下面可能是其中之一

Python3.6引入了
\uuuu init\u subclass\uu
钩子,该钩子在类被子类化之后执行

class MusicFile:
    _register = {}

    def __init_subclass__(cls, **kwargs):
        if not hasattr(cls, 'extension'):
            raise ValueError(cls.__name__ + ' has no extension')

        MusicFile._register.update({e: cls for e in cls.extension})

    @classmethod
    def get_class_by_extension(cls, ext):
        return cls._register.get(ext)
实例
class MP3(音乐文件):
扩展名=['mp3']
类MIDI(音乐文件):
扩展名=['midi']
音乐文件。通过扩展名(“mp3”)获取类
音乐文件。通过扩展(“midi”)获取类

请注意,这与非常类似,但以一种更直接、更易于维护的方式。

此答案仅适用于Python 3.6+。如果您可以选择升级到最新的Python版本,下面可能是其中之一

Python3.6引入了
\uuuu init\u subclass\uu
钩子,该钩子在类被子类化之后执行

class MusicFile:
    _register = {}

    def __init_subclass__(cls, **kwargs):
        if not hasattr(cls, 'extension'):
            raise ValueError(cls.__name__ + ' has no extension')

        MusicFile._register.update({e: cls for e in cls.extension})

    @classmethod
    def get_class_by_extension(cls, ext):
        return cls._register.get(ext)
实例
class MP3(音乐文件):
扩展名=['mp3']
类MIDI(音乐文件):
扩展名=['midi']
音乐文件。通过扩展名(“mp3”)获取类
音乐文件。通过扩展(“midi”)获取类

请注意,这与非常相似,但更直接、更易于维护。

事实上,我正在使用工厂来创建正确的对象,但可能在每次添加新的子类型时,元类都可以构建字典?我想知道元类的一个很好的用途是否是创建一个约束,约束类的外观(例如,它的方法)以使其正常工作。事实上,我正在使用工厂来创建正确的对象,但也许每次添加一个新的子类型时,元类都可以创建它外观所在的字典?我想知道元类的一个很好的用途是否是创建一个约束,约束类的外观(例如,它的方法)以使其正常工作