我想要一个类MyClass
的实例,它们共享一些从文件中读取的常量属性,但是还具有该实例唯一的值的属性。但是,我只想为所有实例读取一次文件。
类似
config.json
{
"a": 1,
"b": 2,
}
然后定义类:
class MyBaseClass:
def __new__(cls):
with open('config.json', 'r') as f:
for key, value in json.load(f).items():
setattr(cls, key, value)
class MyClass(MyBaseClass):
def __init__(self, param):
self.c = param
当我初始化MyClass
的实例时,我想要
inst1 = MyClass("One")
inst2 = MyClass("Two")
使inst1.c
为One
,而inst2.c
为Two
。但是我想以某种方式实现这一点,以便MyBaseClass仅从config.json
读取数据一次。像是单身。我该怎么办?
答案 0 :(得分:1)
您已经拥有大部分框架。首次创建类时,有许多代码会运行。最简单使用的是类主体本身。您可以使用它来创建一个类变量,该类变量包含所需的属性,并带有如下所示的代码段:
class MyBaseClass:
with open('config.json', 'r') as f:
attributes = json.load(f)
def __new__(cls):
self = super().__new__(cls)
self.__dict__.update(cls.attributes)
类命名空间中的 Any 名称在运行该类后仍保留为类变量,而不仅仅是方法。仅当您拥有不使用插槽或具有冲突属性的常规类时,才可以更新字典。在这种情况下,请在setattr
中使用__new__
循环。
答案 1 :(得分:1)
您可以将MyBaseClass
定义为元类,因此只需完成一次。
>>> class MyBaseClass(type):
... def __new__(cls, name, bases, dct):
... x = super().__new__(cls, name, bases, dct)
... print('In metaclass')
... with open('config.json', 'r') as f:
... for key, value in json.load(f).items():
... setattr(x, key, value)
... return x
...
>>>
现在,将MyBaseClass
指定为MyClass
的元类。
>>> class MyClass(metaclass=MyBaseClass):
... def __init__(self, param):
... self.c = param
...
In metaclass
>>>
定义MyClass
时,它将仅调用一次MyBaseClass.__new__
方法。现在,
>>> inst1 = MyClass("One")
>>> inst2 = MyClass("Two")
将导致创建两个实例,而不会进一步读取config.json
。