我在python中寻找一种方法来在python中构建类:
-
setter检查赋值前的值的类型
-
无法添加新的类属性
暂时我找到了这两个装饰器:
def getter_setter_gen(name, type_):
def getter(self):
return getattr(self, "__" + name)
def setter(self, value):
print "setter", value
if not isinstance(value, type_):
raise TypeError("%s attribute must be set to an instance of %s" % (name, type_))
setattr(self, "__" + name, value)
return property(getter, setter)
def auto_attr_check(cls):
new_dct = {}
print "auto_attr_check", cls.__dict__.items()
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:
n = type(cls)(cls.__name__, cls.__bases__, new_dct)
return n
和
def froze_it(cls):
def frozensetattr(self, key, value):
print key
key = ''+key
print(dir(self))
print key
if not hasattr(self, key):
raise TypeError("Class {} is frozen. Cannot set {} = {}"
.format(cls.__name__, key, value))
else:
object.__setattr__(self, key, value)
cls.__setattr__ = frozensetattr
return cls
但加入这两种方法我有很多麻烦 . 你能帮助我吗?你有想法吗?非常感谢
1 回答
您遇到的问题是您的
property
正在使用setattr
来设置属性的值,但是您已经覆盖__setattr__
以使其无法成功 . 对于主要属性名称以及作为属性基础的实际属性的下划线前缀名称(如果setter代码可以达到那么远),hasattr
检查将失败 .我建议两个补充修复 . 首先,更改
hasattr
检查要更加小心 . 如果失败,它还应该检查属性对象的类dict:第二个修复是
setter
函数,它应该绕过底层属性的__setattr__
方法:最后一点:
property
创建的属性名称上的双下划线前缀不会调用名称修改,我怀疑它是你想要的 . 名称修改仅在编译时发生 . 当方法包含类似__bar
的名称时,编译器将名称转换为_NameOfTheClass__bar
(其中NameOfTheClass
是定义方法的类的名称) .在运行时,代码的行为就像被破坏的名称直接写在源代码中一样 . 这意味着
__setattr__
和朋友们没有简单的方法来对动态创建的变量进行名称修改 .如果您只是希望将您的名称非正式地标记为私有(即,它们不是公共API的一部分),您应该使用单个前导下划线 .