我有一个设计问题。我想编写一个方法接受单个对象或对象的可迭代。例如,假设我有 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。water 方法更 Pythonic,因为它使用 Duck Typing。但是,我想进一步讨论。假设我有一个可以给不同类型的动物浇水的看护班:
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)
我还有一些其他的想法,但在我采用特定的设计方法之前,我想从其他可能遇到过此类问题的人那里获得一些意见。如果您也可以列出您的想法的优缺点。那将是一个奖金!谢谢。
更新:到目前为止,似乎有两个同样好的建议。
- 测试传入的参数的行为,例如,编写一个 is_itereable 方法。
- 使用位置参数并遍历位置参数列表中的项目列表。
我还没有确定哪个更适合我的实际问题。