0

蟒蛇 2.5.4。对 Python 来说相当新,昨晚对装饰器来说是全新的。如果我有一个具有多个布尔属性的类:

class Foo(object):
    _bool1 = True
    _bool2 = True
    _bool3 = True
    #et cetera

    def __init__():
        self._bool1 = True
        self._bool2 = False
        self._bool3 = True
        #et cetera

有没有办法使用单个装饰器来检查任何布尔属性的任何设置是否必须是布尔值,并返回任何请求的这些变量之一的布尔值?

换句话说,与每个属性的类似内容相反?

def bool1():
    def get_boo1():
        return self._bool1
    def set_bool1(self,value):
        if value <> True and value <> False:
            print "bool1 not a boolean value. exiting"
            exit()
        self._bool1=value
    return locals()
bool1 = property(**bool1())

#same thing for bool2, bool3, etc...

我试图把它写成这样:

def stuff(obj):
    def boolx():
        def fget(self):
            return obj
        def fset(self, value):
            if value <> True and value <> False:
                print "Non-bool value" #name of object???
                exit()
            obj = value
        return locals()
    return property(**boolx())

bool1 = stuff(_bool1)
bool2 = stuff(_bool2)
bool3 = stuff(_bool3)

这给了我:

File "C:/PQL/PythonCode_TestCode/Tutorials/Decorators.py", line 28, in stuff
    return property(**boolx())
TypeError: 'obj' is an invalid keyword argument for this function

有关如何正确执行此操作的任何指示?

谢谢,

保罗

4

2 回答 2

3

您可以尝试使用描述符

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 Foo(object):
    _bar = False
    bar = BooleanDescriptor('_bar')

编辑:

正如 S.Lott 提到的,python 喜欢Duck Typing而不是类型检查。

于 2009-11-10T14:44:42.580 回答
2

两件重要的事情。

首先,“类级”属性由类的所有实例共享。就像static在 Java 中一样。从您的问题中不清楚您是否真的在谈论类级别的属性。

通常,大多数 OO 编程都是使用实例变量完成的,就像这样。

class Foo(object):
    def __init__():
        self._bool1 = True
        self._bool2 = False
        self._bool3 = True
        #et cetera

第二点。我们不会浪费大量时间来验证参数的类型。

如果一个神秘的“某人”提供了错误的类型数据,我们的课程就会崩溃,这几乎是最好的结果。

忙于类型和域验证需要大量工作才能让您的课程在不同的地方崩溃。归根结底,异常 ( TypeError) 是一样的,所以额外的检查结果证明没有什么实用价值。

事实上,当有人创建一个替代实现bool并且您的类拒绝这个具有与 built-in 所有相同功能的完全有效的类时,额外的域检查可能会(并且经常会)适得其反bool

不要将人工输入范围检查与 Python 类型检查混为一谈。人工输入(或从文件或 URI 中读取的内容)必须进行范围检查,但不能不进行类型检查。读取外部数据的应用程序部分定义了类型。无需检查类型。不会有任何谜团。

“如果我使用了错误的类型并且我的程序似乎可以工作但没有工作怎么办”场景实际上没有任何意义。首先,找到两种行为相同但结果略有不同的类型。唯一的例子是intvs. float,唯一真正重要的是除法,这由两个除法运算符负责。

如果你“不小心”在需要数字的地方使用了一个字符串,你的程序就会死掉。可靠。始终如一。

于 2009-11-10T14:37:09.250 回答