3

データを取得し、データを解析するためのさまざまな関数を持つPythonクラスを作成する場合。最も正しい方法は何ですか?self.data ...を1つずつ入力し、解析関数を実行してself.parsed_data ...を入力するように記述できます。または、self.dataを受け入れてself.parsed_dataを返す関数を記述するのが正しいですか。 。?

以下の例。MyClass1はself.variablesにデータを入力し、MyClass2はそれらをパラメーターとして受け取ります。MyClass2は「最も」正しいと思います。

それで、何が正しいのですか?なぜ?私はしばらくの間、これら2つのコーディングスタイルのどちらかを決定しようとしてきました。しかし、これらのうちどれがベストプラクティスと見なされているかを知りたいです。

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

最後に、それは個人的な好み次第です。parse_dataしかし、IMOは、生データを取り込み、一連の作業を実行し、解析されたデータを返すモジュールレベルの関数を呼び出す方がよいでしょう。キャッシュキーは生データから何らかの形で派生していると思います。つまり、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

2番目の方法は、(私が正しく理解していれば)効率と結果が同じであるが、生データのインスタンスメンバーを持つことを回避するために望ましい方法です。一般に、オブジェクト内に格納されるデータの量を減らしたいと考えています。これは、追加の各属性が、時間の経過に伴う一貫性についてより心配することを意味するためです。

言い換えれば、それは「より機能的」です。

于 2013-03-09T13:56:45.880 に答える
0

この質問について考えてみてください。2つのメソッドを使用する代わりに、このロジックを1つの長いメソッドに結合した場合、解析後に生データを追跡しますか?その答えが「はい」の場合、それを属性として保存することは理にかなっています。ただし、それ以降は気にしない場合は、2番目の形式をお勧めします。ロジックの一部を「ヘルパー」サブルーチンに分割することは、他のメソッドが気にする必要があるかもしれないクラスへの変更を避けることが望ましいでしょう。

于 2013-03-09T13:59:02.367 に答える