Python 3.x 如何在python中初始化类而不是实例

Python 3.x 如何在python中初始化类而不是实例,python-3.x,Python 3.x,我有一门课是这样的: class Metrics: meters = {} for subscription in SUBSCRIPTION_TYPES: meters[subscription] = metrics.new_meter(subscription) @staticmethod def get_meter_data(field, key): return Metrics.meters[field].get()[ke

我有一门课是这样的:

class Metrics:
    meters = {}

    for subscription in SUBSCRIPTION_TYPES:
        meters[subscription] = metrics.new_meter(subscription)

    @staticmethod
    def get_meter_data(field, key):
        return Metrics.meters[field].get()[key]

    @staticmethod
    def track(subscription, value):
        Metrics.meters[subscription].notify(value)

        gauge_for_passport.set_function(lambda: Metrics.meters[subscription].get()["count"])
from types import ModuleType

def init_metrics_module():
    """This is a function to delay creation of the module below."""

    meters = {}

    for subscription in SUBSCRIPTION_TYPES:
        meters[subscription] = new_meter(subscription)

    def get_meter_data(field, key):
        return meters[field].get()[key]

    def track(subscription, value):
        meters[subscription].notify(value)

        gauge_for_passport.set_function(lambda: meters[subscription].get()["count"])


    # create module
    module_dict = locals().copy()
    metrics = ModuleType("metrics")
    metrics.__dict__.update(module_dict)
    return metrics

基本上,我只希望meters字典初始化一次,因为它将跟踪我应用程序中的某些事件,所以我在类主体中有
for
循环。这样做对吗

我是否也应该使用
classmethod
,这样我就可以使用
cls
并将类本身传递给该方法,而不是直接调用
度量值

类在模块运行时被“初始化”。所以当你写这篇文章时:

# my_module.py

class Metrics:
    meters = {}

    for subscription in SUBSCRIPTION_TYPES:
        meters[subscription] = metrics.new_meter(subscription)
…导入my_模块时执行for循环

在我看来,你真正想要的是一个模块,而不是一个类。任何给定模块只有一个实例

# metrics.py module

meters = {}

for subscription in SUBSCRIPTION_TYPES:
    meters[subscription] = new_meter(subscription)

def get_meter_data(field, key):
    return meters[field].get()[key]

def track(subscription, value):
    meters[subscription].notify(value)

    gauge_for_passport.set_function(lambda: meters[subscription].get()["count"])
当您希望它“实例化”时,您只需导入它:

# other_module.py

import metrics
如果您真的不想将此模块放在单独的文件中,可以在另一个模块中动态创建一个模块。但老实说,这可能不值得费心,我甚至不确定您将如何编写模块,但也会延迟其执行

延迟类创建的另一个选项可能是编写类工厂,这是一种pythonic方法,可能有意义,具体取决于您的用例:

def get_metrics():

    class Metrics:
        meters = {}

        for subscription in SUBSCRIPTION_TYPES:
            meters[subscription] = metrics.new_meter(subscription)

        @staticmethod
        def get_meter_data(field, key):
            return Metrics.meters[field].get()[key]

        @staticmethod
        def track(subscription, value):
            Metrics.meters[subscription].notify(value)

            gauge_for_passport.set_function(lambda: Metrics.meters[subscription].get()["count"])

    return Metrics

通过这种方式,您可以控制类的运行时间。但是你的示例代码在我看来并不像一个类;它看起来像是一组属于同一名称空间的工具


让我们有点可笑 回到动态模块创建的想法:您可以将这两个想法结合起来,并执行如下操作:

class Metrics:
    meters = {}

    for subscription in SUBSCRIPTION_TYPES:
        meters[subscription] = metrics.new_meter(subscription)

    @staticmethod
    def get_meter_data(field, key):
        return Metrics.meters[field].get()[key]

    @staticmethod
    def track(subscription, value):
        Metrics.meters[subscription].notify(value)

        gauge_for_passport.set_function(lambda: Metrics.meters[subscription].get()["count"])
from types import ModuleType

def init_metrics_module():
    """This is a function to delay creation of the module below."""

    meters = {}

    for subscription in SUBSCRIPTION_TYPES:
        meters[subscription] = new_meter(subscription)

    def get_meter_data(field, key):
        return meters[field].get()[key]

    def track(subscription, value):
        meters[subscription].notify(value)

        gauge_for_passport.set_function(lambda: meters[subscription].get()["count"])


    # create module
    module_dict = locals().copy()
    metrics = ModuleType("metrics")
    metrics.__dict__.update(module_dict)
    return metrics

然后,当您需要时:

metrics = init_metrics_module()
type(metrics)  # <class 'module'>
metrics=init\u metrics\u模块()
类型(指标)#

看看
单例
。只使用类有什么不对?它们不是只有一个吗?singleton是一个类的实现,它将使用限制在单个实例上。也就是说,不管它被实例化了多少次,所有的实例都使用了相同的基础数据。但是,我并没有将一个类实例化到一个对象中。我会考虑把它放在一个模块中,并消除类体。需要初始化时,可以导入它。一个给定模块只能有一个实例,所以它听起来像是您想要的。