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

标签 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()[key]

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

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

基本上,我只希望计量字典初始化一次,因为它将跟踪我的应用程序中的某些事件,因此我在类主体中有 for 循环。这是正确的方法吗?

我是否还应该使用 classmethod 以便可以使用 cls 并将类本身传递给方法,而不是直接调用 Metrics

最佳答案

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

# my_module.py

class Metrics:
    meters = {}

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

...for 循环在导入 my_module 时执行。

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

# 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

如果您确实不想将此模块放在单独的文件中,可以通过多种方法在另一个模块中动态创建模块。但老实说,这可能不值得这么麻烦,而且我什至不确定如何编写该模块并延迟其执行。

延迟类创建的另一个选项可能是编写一个类工厂,这是一种 Python 方法,根据您的用例可能会有意义:

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

通过这种方式,您可以控制类何时运行。但你的示例代码对我来说确实看起来不太像一个类;它看起来像是属于同一个命名空间的一堆工具。


让我们来点可笑的

回到动态模块创建的想法:您可以将这两个想法结合在一起并执行如下操作:

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'>

关于python-3.x - 如何在Python中初始化类而不是实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57398066/

相关文章:

python - 按组别划分的百分比

python - 如何编写将调用 python3 或 python2 的 shebang 行,以可用者为准

python - 如何从Python3脚本运行Gradle

python-3.x - 如何从 Django 模板中的 API 响应转换日期

python - 基于唯一键简化字典列表的方法

python-3.x - 是否可以通过编程方式使用 pip 安装 python 库?

python - 导入错误 : No module named pip after trying to upgrade pip

python - 如何检查字符串是否为回文?

将函数重新应用到其自己的输出 n 次的 Pythonic 方法?

python - Tornado 处理程序在 python 中 fork 额外的工作