私はクラス以下の例のように、基本的な機能を持っています。コンストラクタは、両方にデフォルト設定されている2つの引数をとり、None
値が指定されていない場合に。クラスの目標は、の値与えられた、ということでfoo
、ユーザーが呼び出すことができるcalculateBar()
の値を計算する機能をbar
。逆に、ユーザは、の値を提供することができる必要がありbar
、その後、呼び出しcalculateFoo()
のための値を計算する機能foo
。特に、これらの機能は、本質的に、互いの逆です。
class ExampleClass:
def __init__(self, foo=None, bar=None):
self.foo = foo
self.bar = bar
# Essentially an XNOR. Raises an exception if:
# 1. Both foo and bar are 'None' (no value given for either)
# 2. Neither foo, nor bar are 'None' (value given for both)
if bool(foo == None) == bool(bar == None):
raise ValueError("Please give a value for Foo or Bar (but not both)")
def calculateFoo(self):
return self.bar / 2.0
def calculateBar(self):
return self.foo * 2.0
私が持っている問題は、私は、ユーザーが値を与えることを可能だけにクラスを制限したいということであるfoo
ORの値をbar
、両方ではなく、それらのすなわち正確に一つには、値を保持する必要があり、他のがあるべきNone
。私の現在の方法は、単純にどちらの場合に例外を発生することでfoo=None and bar=None
、またはfoo!=None and bar!=None
。これは、しかし、洗練解決策のように思えます。ちょうど2つの引数のいずれかを入力するユーザーを制限するための良い方法はありますが、それでもの正しい使用できるようにcalculateFoo()
し、calculateBar()
機能を?私は必要なものを許可するようにクラスを整理する良い方法はありますか?
コメントで示唆したように、あなたはあなたのクラスを分割する可能性がExampleClass
二つの別々のクラスに。現時点では、あなたのクラスは、やろうとしているfoo
ものとbar
物事をが、1つが定義されていない場合は、一方の部材を呼び出すときに定義されていないために提起されている例外の可能性を残しますcalculateFoo()
かcalculateBar()
。
何あなたができることは持っている抽象基本クラスを機能でcalculate()
2つの別々のクラスを派生Foo
し、Bar
これから。あなたの派生クラスは、関数をオーバーライドすることを余儀なくされます。抽象基底クラスは純粋テンプレートです-あなたはそれのインスタンスを作成することはできませんが、それは派生クラス用のテンプレートとして機能します。
例:
from abc import ABC, abstractmethod
class BaseClass(ABC):
@abstractmethod
def calculate(self):
pass
class Foo(BaseClass):
def __init__(self, foo):
self.foo = foo
def calculate(self):
return self.foo / 2.0
class Bar(BaseClass):
def __init__(self, bar):
self.bar = bar
def calculate(self):
return self.bar * 2.0
foo = Foo(10)
print(foo.calculate())
bar = Bar(10)
print(bar.calculate())
出力:
5.0
20.0