python相对较新。我最近发布了一个关于验证数据类型是否为布尔值的问题。 [Use a Descriptor (EDIT: Not a single decorator) for multiple attributes?
给出的答案引用了鸭子打字。我有一个简单的例子,想确保我理解。如果我的代码是:
class Foo4(object):
def __init__(self):
self.bool1=True
def send_rocket(self, bool_value):
if not bool_value:
print "Send rocket ship to sun first... bad move."
print "Send rocket ship to Mars... good move."
f=Foo4()
f.send_rocket(f.bool1)
#Send rocket ship to Mars... good move.
f.bool1=None
f.send_rocket(f.bool1)
#Send rocket ship to sun first... bad move.
#Send rocket ship to Mars... good move.
如果我理解鸭子打字有点正确,在上面的课程中我信任 bool1将永远是一个布尔值:我不应该检查bool1 == False或bool1 == True。当有人错误地使用我的模块时,即bool1 = None,该方法会显示我不想要执行的操作,但没有表明存在问题 ......并且火箭船中的人员死亡。
我可以编写代码以确保bool1始终是一个真正的布尔值的另一种方式是(上面链接中的BooleanDescriptor信用!):
class BooleanDescriptor(object):
def __init__(self, attr):
self.attr = attr
def __get__(self, instance, owner):
return getattr(instance, self.attr)
def __set__(self, instance, value):
if value in (True, False):
return setattr(instance, self.attr, value)
else:
raise TypeError
class Foo4(object):
def __init__(self):
self._bool1=True
bool1 = BooleanDescriptor('_bool1')
def send_rocket(self, bool_value):
if not bool_value:
print "Send rocket ship to sun... bad move."
print "Send rocket ship to Mars... good move."
f=Foo4()
f.send_rocket(f.bool1)
#Send rocket ship to Mars... good move.
f.bool1=None
#TypeError.
#Never gets here: f.send_rocket(f.bool1)
我是否理解第一种方式(不检查)是正确的方法?我的意思是,我总是可以在第一个例子中明确地编写代码:
if bool_value ==True:
print "do something"
elif bool_value == False:
print "do something else"
else:
print "invalid boolean value"
但是如果我在每个使用bool1的方法中都这样做,为什么我会在第一时间没有验证bool1是一个真正的布尔值(DRY!)!?!? : - )
谢谢!
保
答案 0 :(得分:2)
通常的Python风格是第一种方法。
例如,我可能想让你的图书馆使用的东西无法决定是去太阳还是火星,直到最后一刻。所以我可能会传入这个类的实例:
class LastMinuteDecision(object):
def __bool__(self):
return make_decision_now()
如果你在那里遇到了一些测试,认为你比我更了解我将如何调用你的库,那么我就不能这样做了,我会非常生气并且可能会告诉你不要再写Java了(在Python中......或者其他)...
[编辑:如果不清楚,__ bool__方法使实例“看起来像”一个布尔值。当语言需要布尔值时调用它。]
你可能会觉得它很疯狂,但它的效果非常好。
答案 1 :(得分:0)
我希望用一个强制它的类来包装一个动态类型的值,基本上是静态类型的,这是不可取的。
我不是专家,但我希望你的最终方法是最好的方法(即检查是否为真,否则)。