デザインに問題があります。単一のオブジェクトまたはオブジェクトの反復可能オブジェクトのいずれかを受け入れるメソッドを作成したいと思います。たとえば、クラスDogがあるとします。
class Dog(object):
"""
An animal with four legs that may slobber a lot
"""
def __init__(self, name="Fido"):
self.name = name
ここで、Dogクラスを使用するクラスがあるとします。DogWalkerと言います。
class DogWalker(object):
"""
Someone who cares for Fido when Human Companion is not available
"""
def __init__(self):
self.dogs_walked = 0
self.dogs_watered = 0
def walk(self, dogs):
"""
Take a dog for a walk
"""
# This is not Pythonic
if isinstance(Dog, dogs):
# Walk a single dog
pass
self.dogs_walked +=1
else:
# walk lots of dogs
pass
def water(self, dogs):
"""
Provide water to dogs
"""
# More pythonic
try:
# Try to water single dog
...
self.dogs_walked += 1
except AttributeError:
# Try to water lots of dogs
pass
上記の例では、walkとwaterの2つのメソッドを実装しました。水メソッドは、ダックタイピングを使用するという点でよりパイソン的です。ただし、もう少し話を進めたいと思います。さまざまな種類の動物に水をやることができる世話人クラスがあるとしましょう。
class CareTaker(object):
"""
Someone who cares for things
"""
def __init__(self):
self.things_watered = 0
def water(self, things):
"""
Provide water to a thing
"""
# Here is where I need help!
# 1. I need to figure out if things is a single item or iterable
# 2. If thing is a single item I need to figure out what type of thing a thing is
# 3. If thing is an iterable, I need to figure out what type of things are in the iterable.
pass
さて、私が思いついたのは、それぞれが自分自身に水をやる方法を知っているということです。そうすれば、世話人は物事を水法と呼ぶだけで済みます。例えば:
class CareTaker(object):
"""
Someone who cares for things
"""
def __init__(self):
self.things_watered = 0
def water(self, thing):
"""
Provide water to a thing
"""
result = thing.water()
self.things_watered += 1
return result
このようにコードを使用すると、次のようになります。
ct = CareTaker()
dog = Dog()
bird = Bird()
water_dog = ct.water(dog)
water_bird = ct.water(bird)
things = [dog, bird]
for thing in things:
ct.water(thing)
他にもいくつかアイデアがありますが、具体的な設計アプローチをとる前に、そのような問題に直面した可能性のある他の人から意見を聞きたいと思います。あなたのアイデアの長所と短所もリストできれば。それはボーナスになります!ありがとう。
更新:これまでのところ、2つの等しく良い提案があるようです。
- 渡された引数の動作をテストします。たとえば、is_itereableメソッドを記述します。
- 位置引数を使用して、位置引数リスト内の項目のリストを反復処理します。
どちらが実際の問題に適しているかはまだわかりません。