具有一组常量属性的初始化类实例,这些属性在

2024-09-28 22:20:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我想要一个类的一些实例MyClass,它共享从文件中读取的一些常量属性,但是也有一些属性的值对于实例来说是唯一的。但是,我只想对所有实例读取一次文件

像这样的

配置.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就是Oneinst2.c就是Two。但是我想通过一种方式来实现这一点,使得MyBaseClass只从config.json读取一次数据。就像独生子女一样。我该怎么做


Tags: 实例keyselfconfigjson属性paramvalue
2条回答

您可以将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

你已经有了大部分的框架。在第一次创建类时,会运行许多代码。最简单的方法是使用类主体本身。您可以使用它创建一个包含所需属性的类变量,并使用类似于此处所示的代码段:

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)

运行类后,类命名空间中保留的任何名称都将成为类变量,而不仅仅是方法。只有当您有一个不使用插槽或具有冲突属性的常规类时,更新字典才会起作用。在这些情况下,请使用setattr中的__new__循环

相关问题 更多 >