需求描述:类一旦初始化后,禁止更新变量值,且只能初始化一次(单例)。
定义装饰器 readOnlyProperties 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 def readOnlyProperties (*attrs) : """ 变量只读 """ def class_rebuilder (cls) : """The class decorator example""" class NewClass (cls) : """This is the overwritten class""" def __setattr__ (self, name, value) : if name not in attrs: pass elif name not in self.__dict__: pass else : raise AttributeError("Can't touch {}" .format(name)) super().__setattr__(name, value) return NewClass return class_rebuilder
定义Class : Singleton 1 2 3 4 5 6 7 8 9 class Singleton (type) : """ 单例模式 """ _instances = {} def __call__ (cls, *args, **kwargs) : if cls not in cls._instances: cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) return cls._instances[cls]
3.1定ass: Setting class Setting 包含三个实例变量DEBUG
、MEDIA_PATH
,LOG_PATH
。
1 2 3 4 5 6 @readOnlyProperties(['DEBUG','MEDIA_PATH','LOG_PATH']) @dataclass class Setting(object, metaclass=Singleton): DEBUG: bool MEDIA_PATH: str LOG_PATH: str
实例化2个不同实例s0
,s1
。 更新s1.LOG_PATH
和s1.DEBUG
。
1 2 3 4 5 6 7 s0 = Setting(DEBUG=False , MEDIA_PATH='1' , LOG_PATH='2' ) s1 = UIAutoMeta(DEBUG=False , MEDIA_PATH='5' , LOG_PATH='6' ) print(s0) s1.LOG_PATH='3' s1.DEBUG=True print(s0) print(s1)
output0 禁止更新实例变量。
1 AttributeError: Can't update the key:LOG_PATH to value:3
实例化2个不同实例s0
,s1
。
1 2 3 4 5 6 7 s0 = Setting(DEBUG=False , MEDIA_PATH='1' , LOG_PATH='2' ) s1 = UIAutoMeta(DEBUG=False , MEDIA_PATH='5' , LOG_PATH='6' ) print(s0) s1.LOG_PATH='3' s1.DEBUG=True print(s0) print(s1)
output1 s1
和s2
为同一个对象。
1 2 readOnlyProperties.<locals>.class_rebuilder.<locals>.NewClass(DEBUG=False , MEDIA_PATH='1' , LOG_PATH='2' ) readOnlyProperties.<locals>.class_rebuilder.<locals>.NewClass(DEBUG=False , MEDIA_PATH='1' , LOG_PATH='2' )
Python3.7版本 python3.7以后的版本可以这样写 定义一个dataclass,拥有name
和age
两个属性 实例化一个People
,然后尝试对其age
进行重新赋值。
1 2 3 4 5 6 7 8 9 10 11 from dataclasses import dataclass@dataclass(frozen=True) class People : name: str age: int davida = People(name='davida' , age=28 ) davida.age = 29
输出
1 2 3 4 5 Traceback (most recent call last): File "E:/workspaces/python/pytorchLearn/ttt.py" , line 18 , in <module> davida.age = 29 File "<string>" , line 3 , in __setattr__ dataclasses.FrozenInstanceError: cannot assign to field 'age'