私の質問は、関数内で数回必要とされ、他の場所では必要とされないコードの編成について言及しています。
次の使用例を想定しています。
class A(object):
def __init__(self, base):
self.base = base
def foo(self):
result = self.base + 2 # Should go to an extra function.
result = result * 4
if result > 10:
result = result + 2 # Should go to an extra function.
return result
def bar(self):
pass
私のプロジェクトでは、抽象化する必要がある 20 行のコード (別のオブジェクトの 20 の属性に値を追加する)foo()
の部分に繰り返しがあります。x + 2
しかし、それらをどこに置くのですか?それを行うには3つの方法があります。
(1.)ネストされた関数:
class A(object):
# ...
def foo(self):
def plus_two(value):
return value + 2
result = plus_two(self.base)
result = result * 4
if result > 10:
result = plus_two(result)
return result
# ...
これは、メソッド内で発生することのみに関連する非常に特殊なユース ケースであるため、理にかなっているように思われます。
ただし、テストできません。単体テストのためにネストされた関数に外部からアクセスすることはできません。そして、これをの一部としてテストしたくありません.2回すべてをfoo()
テストする必要があるためです(両方の場合)。単体テストでは、個別にテストすることが可能であるべきであり、.plus_two
plus_two
foo()
(2.)ヘルパー メソッド:
class A(object):
# ...
def foo(self):
result = self.plus_two(self.base)
result = result * 4
if result > 10:
result = self.plus_two(result)
return result
def plus_two(self, value):
return value + 2
# ...
ただし、そのメソッドはクラス内の他のメソッドによって使用されることはなく、 へのアクセスも必要self
ないため、そのクラスのメソッドになるべきではありません。オブジェクトへのアクセスを必要としない、またはインターフェイスの一部として上書きする必要がないクラスで関数を収集することは Pythonic ではありません。
(3.)モジュール機能:
def plus_two(value):
return value + 2
class A(object):
# ...
def foo(self):
result = plus_two(self.base)
result = result * 4
if result > 10:
result = plus_two(result)
return result
# ...
しかし: これにより、いくつかのヘルパー関数が非常に具体的なコンテキストから取り出されます。つまり、カプセル化には従いません。これはここでは問題ではないようで、解決策のように見えるかもしれませんが、私のプロジェクトでは、関数は一般的にモジュールに関連していないため、これはモジュール全体を本当に混乱させますが、前述のように、非常に具体的ですつまり、これをそのコンテキストから遠く離れた場所に分割すると、コードが非常に読みにくくなり、pythonic が少なくなります。
他に方法はありますか、またはここに示す 3 つの方法のいずれかを選択する必要がありますか?