如何动态创建具有只读属性的对象
How to create object having read-only attributes dynamically
我想创建具有只读属性的对象。
并且需要动态初始化。
这是我想要的情况。
readOnlyObject = ReadOnlyClass({'name': 'Tom', 'age': 24})
print(readOnlyObject.name)
>> 'Tom'
print(readOnlyObject.age)
>> 24
readOnlyObject.age = 14
>> AttributeError: can't set attribute
我使用 property
函数找到了一个 ,
但我认为 property
函数仅适用于预先声明的属性。
这是我的代码,property
不起作用。
class ReadOnlyClass:
_preDeclaredVar = "Read-Only!"
preDeclaredVar = property(lambda self: self._preDeclaredVar)
def __init__(self, data: dict):
for attr in data:
setattr(self, '_' + attr, data[attr])
setattr(self, attr, property(lambda self: getattr(self, '_' + attr)))
readOnlyObject = ReadOnlyClass({'name': 'Tom', 'age': 24})
print(readOnlyObject.preDeclaredVar)
>> "Read-Only!"
readOnlyObject.preDeclaredVar = "Can write?"
>> AttributeError: can't set attribute '
print(readOnlyObject.name)
>> <property object at 0x016C62A0> # I think it is weird.. property func only work on pre-declared variable?
发生了什么事?
我想知道有没有办法动态创建只读对象。
考虑从 __setattr__
开始:
>>> class ReadOnlyClass:
... def __init__(self, **kwargs):
... self.__dict__.update(kwargs)
...
... def __setattr__(self, key, value):
... raise AttributeError("can't set attribute")
...
>>> readonly_object = ReadOnlyClass(name='Tom', age=24)
>>> readonly_object.name
'Tom'
>>> readonly_object.age
24
>>> readonly_object.age = 10
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in __setattr__
AttributeError: can't set attribute
但是,这可能并不完全符合您的期望。您仍然可以通过 __dict__
:
设置属性
>>> readonly_object.__dict__['age'] = 10
>>> readonly_object.age
10
您可以使用命名元组:
>>> import collections
>>> def ReadOnlyClass(data):
... class_ = collections.namedtuple('ReadOnlyClass', data.keys())
... return class_(**data)
...
>>> readOnlyObject = ReadOnlyClass({'name': 'Tom', 'age': 24})
>>> print(readOnlyObject.name)
Tom
>>> print(readOnlyObject.age)
24
>>> readOnlyObject.age = 14
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
我想创建具有只读属性的对象。 并且需要动态初始化。
这是我想要的情况。
readOnlyObject = ReadOnlyClass({'name': 'Tom', 'age': 24})
print(readOnlyObject.name)
>> 'Tom'
print(readOnlyObject.age)
>> 24
readOnlyObject.age = 14
>> AttributeError: can't set attribute
我使用 property
函数找到了一个
但我认为 property
函数仅适用于预先声明的属性。
这是我的代码,property
不起作用。
class ReadOnlyClass:
_preDeclaredVar = "Read-Only!"
preDeclaredVar = property(lambda self: self._preDeclaredVar)
def __init__(self, data: dict):
for attr in data:
setattr(self, '_' + attr, data[attr])
setattr(self, attr, property(lambda self: getattr(self, '_' + attr)))
readOnlyObject = ReadOnlyClass({'name': 'Tom', 'age': 24})
print(readOnlyObject.preDeclaredVar)
>> "Read-Only!"
readOnlyObject.preDeclaredVar = "Can write?"
>> AttributeError: can't set attribute '
print(readOnlyObject.name)
>> <property object at 0x016C62A0> # I think it is weird.. property func only work on pre-declared variable?
发生了什么事?
我想知道有没有办法动态创建只读对象。
考虑从 __setattr__
开始:
>>> class ReadOnlyClass:
... def __init__(self, **kwargs):
... self.__dict__.update(kwargs)
...
... def __setattr__(self, key, value):
... raise AttributeError("can't set attribute")
...
>>> readonly_object = ReadOnlyClass(name='Tom', age=24)
>>> readonly_object.name
'Tom'
>>> readonly_object.age
24
>>> readonly_object.age = 10
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in __setattr__
AttributeError: can't set attribute
但是,这可能并不完全符合您的期望。您仍然可以通过 __dict__
:
>>> readonly_object.__dict__['age'] = 10
>>> readonly_object.age
10
您可以使用命名元组:
>>> import collections
>>> def ReadOnlyClass(data):
... class_ = collections.namedtuple('ReadOnlyClass', data.keys())
... return class_(**data)
...
>>> readOnlyObject = ReadOnlyClass({'name': 'Tom', 'age': 24})
>>> print(readOnlyObject.name)
Tom
>>> print(readOnlyObject.age)
24
>>> readOnlyObject.age = 14
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute