2009-11-10 35 views
1

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. 

如果我没有理解鸭打字有点正确,在上面的I类信任是BOOL1将永远是一个布尔值:我不应该检查是否BOOL1 ==虚假或BOOL1 = =真。当某人错误地使用我的模块,即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!)!?!? :-)

谢谢!

保罗

回答

2

通常的Python风格是第一种方法。

例如,我可能想用你的图书馆的某些东西不能决定是否要去太阳还是去火星,直到最后一刻。所以我可能会通过在这个类的一个实例:

class LastMinuteDecision(object): 

    def __bool__(self): 
     return make_decision_now() 

如果你已经陷在里面一些测试,以为你知道的比我好我怎么打算打电话给你的图书馆,那么我不能做到这一点,我会非常恼火,并可能告诉你停止在Python中编写Java(或其他)...

[编辑:如果不清楚,__bool__方法使实例看起来像一个布尔值。它在语言期望布尔值时调用。]

您可能会觉得它很疯狂,但它的工作方式非常出色。

0

我期望与包装迫使它是,从本质上讲,静态类型的一类动态类型的值是不是要走的路。

我不是专家,但我期望你的最终方法是最好的方法(即检查真,假或其他)。