7

簡略化すると、次のような Python クラスがいくつかあります。

class base:
    def __init__(self, v):
        self.value = v

    def doThings(self):
        print "Doing things."

    def doMoreThings(self):
        print "Doing more things."

    def combine(self, b):
        self.value += b.value

class foo(base):
    def showValue(self):
        print "foo value is %d." % self.value

class bar(base):
    def showValue(self):
        print "bar value is %d." % self.value

このクラスには、とサブクラスの両方に共通の機能を実装するメソッド (上でと でbase表されている) が含まれています。とサブクラスは、フィールドの解釈方法が本質的に異なります。(上記では、印刷時に表示される内容のみが異なりますが、実際のアプリケーションでは、より複雑な他のいくつかのことを実行します。) 「抽象的」と考えることができます。ユーザーはs とs のみを操作します。 サブクラスに共通するコードのホームとしてのみ存在します。doThingsdoMoreThingsfoobarfoobarvaluebasefoobarbase

私が質問したい方法はcombine、これらのオブジェクトを 2 つ取り、3 番目のオブジェクトを作成する方法です。fooと のbar解釈が異なるため、異なる型の2つのサブクラスにはvalue意味がありません。それでも、 の手順はすべてのサブクラスで同じであるため、分解して 1 か所で定義することは理にかなっています。combinecombinefoofoobarbarfoobarcombine

ユーザーが 2 つの互換性のないオブジェクトを使用しようとした場合、おそらくエラーを通知したいと思いcombineますが、醜い型チェックを導入せずにこれを行う方法がわかりません。これを行うのは良い習慣ですか?または、チェックせずに通常のことを行い、問題を文書化し、ユーザーがcombine意図しない方法で使用しようとしないと想定する必要があります。そのような使用が「成功」してガベージオブジェクトを返すように見えてもエラーを発生させる代わりに?

ご協力ありがとうございました。

4

4 に答える 4

3

ここにいくつかのアプローチがあります:

  1. 何もチェックせず、ユーザーが正しいことを行うと信頼してください。状況に応じて、適切または危険な場合があります。

  2. タイプを確認してください。あなたはそれが醜く見えるのは正しいですが、最も簡単なことです。

  3. はありませんが、value意図したとおりに名前を付け ( pressuretemperature)、それらを結合させます。

  4. 3 と同じですが、さらにサブクラスにpropertyアクセスを.valueそれぞれの「実際の」値変数にマップする があります。このようにして、. __init__()、ただし、.combine()すべてのサブクラスで実行する必要があります。

  5. 4 と同じですが、 は使用しませんpropertyが、自作の記述子です。この回答では、それを行う方法を示します。

于 2013-05-10T06:57:14.820 に答える
2

結合方法を変更する

def combine(self, b):
    if (not(self.__class__.__name__ == b.__class__.__name__)):
        raise TypeError("%s cannot combine with %s" % ( self.__class__.__name__, b.__class__.__name__))
    else:        
        self.value += b.value

または、base のクラス定義を次のように変更します。

class base(object):

そして、よりシンプルで、より良い、より幸せな結合方法が可能です (thanks glglgl)

def combine(self, b):
    if (not(type(self) == type(b))):
        raise TypeError("%s cannot combine with %s" %
                        ( type(self), type(b) ))
    else:        
        self.value += b.value
于 2013-05-10T07:11:02.403 に答える
0

失敗しないプロダクションコードに取り組んだとき、危険な関数が爆発して火の玉になり、システム全体を吹き飛ばさないようにデコレータを使用しました。

def bulltproof(func):
    def _bulletproof(*args, **kwargs):
        try:
            result = func(*args, **kwargs)
        except Exception as exc:
            raise BulletproofError(exc)
        return result
    return _bulletproof

そのように使用します:

@bulletproof
def some_risky_function():
    #....

そして、エラーを 1 つだけキャッチします。

try:
    some_risky_function()
except Bulletproof:
...

エラーを発生させる代わりに、 を返したり、エラーをNoneログに記録したり、テストのためにオフにしたりできます。もちろん、このアプローチは、プログラムがエラーから確実に回復するようにしたい場合に役立ちますが、エラーを続けるよりも、死ぬ方がよい場合もあります。

于 2013-05-10T07:15:24.290 に答える