1

相对较新的python。我最近发布了一个关于验证数据类型是否为布尔值的问题。[对多个属性使用描述符(编辑:不是单个装饰器)?

给出的答案参考了鸭子打字。我有一个简单的例子,并想确保我理解。如果我的代码是:

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!)!?!?:-)

谢谢!

保罗

4

2 回答 2

2

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

例如,我可能想用你的图书馆来处理直到最后一刻才能决定是去太阳还是去火星的东西。所以我可能会传入这个类的一个实例:

class LastMinuteDecision(object):

    def __bool__(self):
        return make_decision_now()

如果你在里面放了一些测试,认为你比我更清楚我将如何调用你的库,那么我不能那样做,我会很生气,可能会告诉你停止编写 Java(或其他)在 Python...

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

你可能认为这很疯狂,但它的效果出奇的好。

于 2009-11-10T17:24:18.977 回答
0

我希望用一个强制它本质上是静态类型的类来包装一个动态类型的值不是要走的路。

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

于 2009-11-10T16:44:11.413 回答