【问题标题】:Writing big python classes the right way [closed]以正确的方式编写大型 python 类[关闭]
【发布时间】:2013-03-09 13:43:47
【问题描述】:

当编写具有不同功能的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()

【问题讨论】:

    标签: python class coding-style


    【解决方案1】:

    这最终取决于个人喜好。但是 IMO,最好只有一个名为 parse_data 的模块级函数,它接收原始数据,执行大量工作并返回解析的数据。我假设您的缓存键以某种方式源自原始数据,这意味着 parse_data 函数也可以实现您的缓存逻辑。

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

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

    【讨论】:

      【解决方案2】:

      对我来说,最正确的类是用户理解和使用的类,错误越少越好。

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

      mc2 = MyClass2()
      print mc1.get_parsed_data()
      

      我只想要

      print get_parsed_data()
      

      有时候not write classes 会更好。

      【讨论】:

      • 这个例子不应该是一个类。但它是另一个类的一个非常简单的版本,应该是一个类:) 但是感谢链接,不应该仅仅因为我们可以使用类..
      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-10-20
          • 1970-01-01
          • 1970-01-01
          • 2011-07-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多