web-dev-qa-db-ja.com

コンストラクターでリストを作成することは、コンストラクターが機能してはならないというガイドラインに違反していますか?

私はこれらのページを読んでいました( 12 、)が、これがガイドラインに違反しているかどうかはまだわかりません。

次のデータをWebサイトから読み取っています。

_Date: July 13, 2018 
Type: Partial Solar Eclipse
Location: South in Australia, Pacific, Indian Ocean

Date: July 27, 2018 
Type: Total Lunar Eclipse
Location: Much of Europe, Much of Asia, Australia, Africa, South in North America
_

データを表すオブジェクトが作成され、クライアントはメソッドを呼び出してデータを処理できます。

私のオブジェクトでは、検索が簡単なため、場所はstringのままになっています。次に例を示します。

_class Eclipse():

    def __init__(self, Eclipse_location):
       # left out other variables and validation to keep it clear and concise
        self._Eclipse_location = Eclipse_location

    def takes_place_in(self, country):
        country_formatted = country.strip().title()
        return country_formatted in self._Eclipse_location
_

このように、たとえば「Much of」や「Parts of」など、国を囲む他の単語に関係なく、True 。場所がlistに分割されている場合は、stringを作成し、国に参加して「ここに国を挿入」を作成し、そのstringの検索を実行する必要があります。また、サイトのどの部分がスクレイピングされているかによっては、「Much of」というフレーズが常に使用されるとは限りません。たとえば、_South in Australia_のように具体的になることもあります。 、つまり、南(そしておそらく北、東、西)に対応するために私の方法を変更する必要があります。メソッドを両方の方法で記述し、それをstringとして保持する方が簡単であり、それでも希望する動作が得られるため、私は知っています。

場所のリストを作成したい場合、このメソッドを呼び出すと、コンストラクターが機能してはならないというガイドラインに違反するとしますか?

_class Eclipse():

    def __init__(self, Eclipse_location):
       # left out other variables and validation to keep it clear and concise
        self._Eclipse_location = Eclipse_location
        self._locations_list = self._locations_as_list(self._Eclipse_location)

    def _locations_as_list(self, str_to_convert):
        return str_to_convert.split(",")
_

オブジェクトが作成された後listは変更されず、listを変更(追加または削除)するメソッドは存在しません。とにかく、コンストラクターでリストを1回作成し、必要なときにlistを呼び出すのは理にかなっています。コンストラクターでlistを作成しない場合、場所のlistが必要になると、_locations_as_list(self, str_to_convert):を呼び出す必要があります。これは非効率に思えます。小さなlistの場合は問題ないかもしれませんが、そのlistに100以上の要素が含まれているとしたらどうでしょうか。

1
user306112

はい。文字列をコンストラクターのリストロジックに配置するのは悪い習慣です。

その文字列の解析がうまくいかない可能性のあるものはたくさんあり、ロジックがコンストラクターにある場合はエラーに対処する機会がほとんどありません。

リストする場所の文字列を解析するクラスを作成した場合はどうなるかを検討してください。

次の関数を含めます。

class LocationParser():
    def IsValid(str_to_convert) #return true if the string can be parsed.

    def Validate(str_to_convert) #return a list of validation errors such as :

        #"illegal character found at pos x", 
        #"unknown country!", 
        #"duplicate country"

    def Parse(str_to_convert) #return the list of locations

どちらの関数も、nullまたは非常に長い文字列などの例外をスローする可能性があります

これで、オブジェクトの2番目のバージョンを作成してさまざまな言語を処理したり、関数を拡張したりできるため、たとえば、使用する区切り文字のリストをコンマではなく渡すことができます。

    def Parse(str_to_convert, delimiters) #return the list of locations

そのすべてのロジックをコンストラクターに入れようとすると、検証エラーを返す方法や区切り文字のセットを渡す方法、異なる形式の文字列にロジックを変更する方法など、いくつかの問題に直面します。

Eclipseオブジェクトで別のオブジェクトまたはメソッドを使用すると、継承または構成によって、あるいは単に別のオブジェクトを保持することによって、動作をオーバーライドできます。

2
Ewan