Python 解析来自4个不同API的响应的正确OOP方法是什么?

Python 解析来自4个不同API的响应的正确OOP方法是什么?,python,oop,Python,Oop,什么是正确的编码方法,例如,一个Weather类,它解析4个不同的源?我是这样做的: 创建了一个名为Weather的类,该类具有4个属性,如temp、windspeed、pressure、湿度和4个方法,如parse_source1、…、parse_source4。为了得到结果,我创建了4个对象,并对每个对象调用不同的方法 但现在我不知道这是否是解决这个问题的正确方法。也许我应该创建具有所有属性的Weather类,然后使用继承并将解析放到init中?最好将Weather类与解析代码分开,即 cl

什么是正确的编码方法,例如,一个Weather类,它解析4个不同的源?我是这样做的:

创建了一个名为Weather的类,该类具有4个属性,如temp、windspeed、pressure、湿度和4个方法,如parse_source1、…、parse_source4。为了得到结果,我创建了4个对象,并对每个对象调用不同的方法


但现在我不知道这是否是解决这个问题的正确方法。也许我应该创建具有所有属性的Weather类,然后使用继承并将解析放到init中?

最好将Weather类与解析代码分开,即

class Weather:
    def __init__(...):
        ...

def parse_weather(source):
    if source == ...:
        ...
    return Weather(...)
这样,当您添加或删除源时,您的类就不必更改。您甚至可以创建一个单独的类

class WeatherParser:
    def __init__(source):
        ...
    def parse_weather(...):
        ...
        return Weather(...)

其中将包含解析方法

最好将Weather类与解析代码分开,即

class Weather:
    def __init__(...):
        ...

def parse_weather(source):
    if source == ...:
        ...
    return Weather(...)
这样,当您添加或删除源时,您的类就不必更改。您甚至可以创建一个单独的类

class WeatherParser:
    def __init__(source):
        ...
    def parse_weather(...):
        ...
        return Weather(...)
这将包含您的解析方法

我不确定这是否是一个合适的问题,因为可能有太多正确的方法,但无论如何,这是一个我发现太多次的问题,同样的解决方案总是对我有效,在不同的语言中

我认为最好为每个对象都有一个解析器类:

class JSONWeatherParser(object):
    def parse(self, value):
        json_obj =  json.load(value)
        w = Weather()
        # Do some stuff here, assign values from json_obj to w etc.
        return w

class XMLWeatherParser(object):
    def parse(self, value):
        element = xml.etree.ElementTree(value)
        w = Weather()
        # Do some stuff here, assign values from element to w etc.
        return w

class YAMLWeatherParser(object):
    def parse(self, value):
        w = Weather()
        # Sorry, I do not even know what it looks like
        return w
把课程放在听写上也很酷:

weather_parsers = {
    'xml': XMLWeatherParser,
    'json': JSONWeatherParser,
    'yaml': YAMLWeatherParser
}
现在,您可以简单地执行以下操作:

format = request.get('format') # For example
data = request.get('weather')
parser = weather_parsers[format]()
weather = parser.parse(data)
事实上,在Python中,您甚至不需要这些*WeatherParser类:您可以创建*WeatherParser函数,这将更简单:

def json_weather_parse(value):
    json_obj =  json.load(value)
    w = Weather()
    # Do some stuff here, assign values from json_obj to w etc.
    return w

def xml_weather_parse(value):
    element = xml.etree.ElementTree(value)
    w = Weather()
    # Do some stuff here, assign values from element to w etc.
    return w

def yaml_weather_parse(value):
    w = Weather()
    # Sorry, I do not even know what it looks like
    return w
如果您的解析器只做一件事,而解析器不保留状态,那么函数是更好的选择。OTOH类方法更通用、语言独立且功能强大。关键是,你可能不需要那么大的能量

总结:虽然从理论上讲,为每种行为上不同的天气课是很酷的,但所有的孩子都在这样做或者,在90年代,实际上,将解析问题从模型中分离出来似乎更容易管理

编辑:Hannes Ovrén提出了一个很好的问题

实际上,解析器类更复杂,我更愿意使用解析器函数。现在,为什么不让它们成为天气预报方法呢?好吧,解析某个特定类的实例并不像这个类所期望的那样,因此将这个问题放在不同的位置似乎更好。当然,我们不会期望一个不存在的实例解析自己

当然,我们可以把它放在一个类方法上,就像Django等人所做的那样。但是,如果函数可以这样做,为什么还要创建一个方法呢?在这种情况下,它更多的是与风格和我玩

更重要的是,从某种意义上说,这是一个风格问题,我的方法就是所描述的方法。然而,我知道这只是一种方法,还有许多其他方法与此方法一样有用和正确。我不认为类方法是错误的,但我也不会使用它们。

我不确定这是一个正确的问题,因为可能有太多正确的方法,但无论如何,这是一个我发现太多次的问题,同样的解决方案总是对我有效,在不同的语言中

我认为最好为每个对象都有一个解析器类:

class JSONWeatherParser(object):
    def parse(self, value):
        json_obj =  json.load(value)
        w = Weather()
        # Do some stuff here, assign values from json_obj to w etc.
        return w

class XMLWeatherParser(object):
    def parse(self, value):
        element = xml.etree.ElementTree(value)
        w = Weather()
        # Do some stuff here, assign values from element to w etc.
        return w

class YAMLWeatherParser(object):
    def parse(self, value):
        w = Weather()
        # Sorry, I do not even know what it looks like
        return w
把课程放在听写上也很酷:

weather_parsers = {
    'xml': XMLWeatherParser,
    'json': JSONWeatherParser,
    'yaml': YAMLWeatherParser
}
现在,您可以简单地执行以下操作:

format = request.get('format') # For example
data = request.get('weather')
parser = weather_parsers[format]()
weather = parser.parse(data)
事实上,在Python中,您甚至不需要这些*WeatherParser类:您可以创建*WeatherParser函数,这将更简单:

def json_weather_parse(value):
    json_obj =  json.load(value)
    w = Weather()
    # Do some stuff here, assign values from json_obj to w etc.
    return w

def xml_weather_parse(value):
    element = xml.etree.ElementTree(value)
    w = Weather()
    # Do some stuff here, assign values from element to w etc.
    return w

def yaml_weather_parse(value):
    w = Weather()
    # Sorry, I do not even know what it looks like
    return w
如果您的解析器只做一件事,而解析器不保留状态,那么函数是更好的选择。OTOH类方法更通用、语言独立且功能强大。关键是,你可能不需要那么大的能量

总结:虽然从理论上讲,为每种行为上不同的天气课是很酷的,但所有的孩子都在这样做或者,在90年代,实际上,将解析问题从模型中分离出来似乎更容易管理

编辑:Hannes Ovrén提出了一个很好的问题

实际上,解析器类更复杂,我更愿意使用解析器函数。现在,为什么不让它们成为天气预报方法呢?好吧,解析某个特定类的实例并不像这个类所期望的那样,因此将这个问题放在不同的位置似乎更好。当然,我们不会期望一个不存在的实例解析自己

当然,我们可以把它放在一个类方法上,就像Django等人所做的那样。但是,如果函数可以这样做,为什么还要创建一个方法呢?在这种情况下,它更多的是与风格和我玩

更重要的是,从某种意义上说,这是一个风格问题,我的方法就是所描述的方法。然而,我知道这只是一种方法,还有许多其他方法与此方法一样有用和正确。我不认为类方法是错误的,但我也不会使用它们<
/p> 如果您是该类的唯一实现者,我会使用@classmethod decorators来创建工厂函数。通过这种方式,解析器/源很容易找到,因为它们是Weather类的一部分

如果您希望其他人使用您的类,并且可能希望实现他们自己的源代码,那么我认为您有两个很好的选择:

在uuu init_uuuu中进行解析,并让用户对天气基类进行子类化

创建一个WeatherParser基类,并让用户从中继承

我认为第一个选项更直观,因为您避免创建更多的类。
在我看来,最重要的是,添加新源的正确方法毫无疑问。

如果您是该类的唯一实现者,我会使用@classmethod decorators来创建工厂函数。通过这种方式,解析器/源很容易找到,因为它们是Weather类的一部分

如果您希望其他人使用您的类,并且可能希望实现他们自己的源代码,那么我认为您有两个很好的选择:

在uuu init_uuuu中进行解析,并让用户对天气基类进行子类化

创建一个WeatherParser基类,并让用户从中继承

我认为第一个选项更直观,因为您避免创建更多的类。
在我看来,最重要的是,添加新资源的正确方法毫无疑问。

非常感谢您快速、有用的回答!非常感谢您快速、有用的回答!非常感谢你详尽的回答,在我读过之后,现在看起来很明显。我肯定会使用您的方法。为什么您觉得最好使用单独的解析器类来实例Weather对象,而不是进行子分类?“你并没有真正为它提供任何论据。”汉内索夫伦问得好。我的答案变得太大了,所以我在我的帖子中以编辑的形式回答。非常感谢你的广泛回答,在我读过之后,现在看起来很明显。我肯定会使用您的方法。为什么您觉得最好使用单独的解析器类来实例Weather对象,而不是进行子分类?“你并没有真正为它提供任何论据。”汉内索夫伦问得好。我的答案太大了,所以我在帖子中以编辑的形式回答。