3

在编写具有不同功能的python类来获取数据和解析数据时;什么是最正确的方法?您可以编写它以便一个接一个地填充 self.data...,然后运行解析函数来填充 self.parsed_data.... 或者编写接受 self.data 并返回 self.parsed_data 的函数是否正确。 .?

下面的例子。MyClass1 填充 self.variables,MyClass2 将它们作为参数。我认为 MyClass2 是“最”正确的。

那么,什么是正确的?为什么?一段时间以来,我一直试图决定这两种编码风格中的哪一种。但我想知道其中哪些被认为是最佳实践。

class MyClass1(object):
    def __init__(self):
        self.raw_data = None

    def _parse_data(self):
        # This is a fairly complex function xml/json parser
        raw_data = self.raw_data
        data = raw_data  #  Much for is done to do something with raw_data
        cache.set('cache_key', data, 600)  # Cache for 10 minutes
        return data

    def _populate_data(self):
        # This function grabs data from an external source
        self.raw_data = 'some raw data, xml, json or alike..'

    def get_parsed_data(self):
        cached_data = cache.get('cache_key')
        if cached_data:
            return cached_data
        else:
            self._populate_data()
            return self._parse_data()

mc1 = MyClass1()
print mc1.get_parsed_data()


class MyClass2(object):
    def _parse_data(self, raw_data):
        # This is a fairly complex function xml/json parser
        data = raw_data  # After some complicated work of parsing raw_data
        cache.set('cache_key', data, 600)  # Cache for 10 minutes
        return data

    def _get_data(self):
        # This function grabs data from an external source
        return 'some raw data, xml, json or alike..'

    def get_parsed_data(self):
        cached_data = cache.get('cache_key')
        if cached_data:
            return cached_data
        else:
            return self._populate_data(self._get_data())

mc2 = MyClass2()
print mc1.get_parsed_data()
4

4 回答 4

2

最后还是看个人喜好。但是IMO,最好只调用一个模块级函数parse_data,该函数接收原始数据,完成大量工作并返回解析后的数据。我假设您的缓存键以某种方式源自原始数据,这意味着该parse_data函数还可以实现您的缓存逻辑。

我更喜欢一个函数而不是一个完整的类的原因是简单。如果你想要一个类来提供从你的原始数据中提取的数据字段,这样你的对象的用户就可以做类似的事情,obj.some_attr而不必查看一些较低级别的数据结构(例如 JSON、XML、Python dict 等)。 ),我会创建一个简单的“值对象”类,它只包含数据字段,没有解析逻辑,并让上述parse_data函数返回这个类的实例(本质上充当数据类的工厂函数)。这导致更少的状态、更简单的对象和没有惰性,使你的代码更容易推理。

这也将更容易对此类的消费者进行单元测试,因为在这些测试中,您可以简单地使用字段实例化数据对象,而不必提供大量测试原始数据。

于 2013-03-09T13:59:14.843 回答
1

对我来说,最正确的类是用户理解和使用的类,并且错误尽可能少。

当我看第 2 课时,我问自己我将如何使用它...

mc2 = MyClass2()
print mc1.get_parsed_data()

我只想

print get_parsed_data()

有时最好根本不编写类

于 2013-03-09T14:07:06.367 回答
0

第二种方式更可取,因为(如果我理解正确的话)它在效率和结果上是相同的,但避免了原始数据的实例成员。通常,您希望减少存储在对象中的数据量,因为每个额外的属性都意味着随着时间的推移更加担心一致性。

换句话说,它“更实用”。

于 2013-03-09T13:56:45.880 回答
0

以这种方式思考这个问题:如果你将这个逻辑组合成一个长方法,而不是两个方法,你会在原始数据解析后跟踪它吗?如果答案是肯定的,那么将其存储为属性是有意义的。但是,如果在那之后您不再关心它,请选择第二种形式。将部分逻辑分解为“帮助”子例程应该最好避免对其他方法可能需要关心的类进行更改。

于 2013-03-09T13:59:02.367 回答