您可以像其他答案一样使用属性-因此,如果您想约束单个属性,例如说“ bar”,并将其约束为整数,则可以编写如下代码:
class Foo(object): def _get_bar(self): return self.__bar def _set_bar(self, value): if not isinstance(value, int): raise TypeError("bar must be set to an integer") self.__bar = value bar = property(_get_bar, _set_bar)
这有效:
>>> f = Foo()>>> f.bar = 3>>> f.bar3>>> f.bar = "three"Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in _set_barTypeError: bar must be set to an integer>>>
(还有一种新的属性编写方法,使用内置的“属性”作为getter方法的装饰器-但我更喜欢旧方法,就像我上面提到的那样)。
当然,如果您的类具有很多属性,并希望以这种方式保护所有属性,那么它就会变得冗长。不用担心-
Python的自省功能允许创建一个类装饰器,该装饰器可以用最少的行自动实现。
def getter_setter_gen(name, type_): def getter(self): return getattr(self, "__" + name) def setter(self, value): if not isinstance(value, type_): raise TypeError(f"{name} attribute must be set to an instance of {type_}") setattr(self, "__" + name, value) return property(getter, setter)def auto_attr_check(cls): new_dct = {} for key, value in cls.__dict__.items(): if isinstance(value, type): value = getter_setter_gen(key, value) new_dct[key] = value # Creates a new class, using the modified dictionary as the class dict: return type(cls)(cls.__name__, cls.__bases__, new_dct)
然后,您仅用
auto_attr_check作类装饰器,并在类主体中声明要与属性也需要约束的类型相等的属性:
... ... @auto_attr_check... class Foo(object):... bar = int... baz = str... bam = float... >>> f = Foo()>>> f.bar = 5; f.baz = "hello"; f.bam = 5.0>>> f.bar = "hello"Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in setterTypeError: bar attribute must be set to an instance of <type 'int'>>>> f.baz = 5Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in setterTypeError: baz attribute must be set to an instance of <type 'str'>>>> f.bam = 3 + 2jTraceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in setterTypeError: bam attribute must be set to an instance of <type 'float'>>>>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)