【问题标题】:How to correctly call preloader function before imports in Python?如何在 Python 中导入前正确调用预加载器函数?
【发布时间】:2020-07-28 19:08:15
【问题描述】:

我有应该在另一个代码之前加载的配置数据(因为另一个代码使用它)。 所以,目前我认为唯一的方法是在导入之前调用顶部的函数:

from Init.Loaders.InitPreLoader import InitPreLoader
# this is my config loader
InitPreLoader.load()

from World.WorldManager import WorldManager
from Init.Loaders.InitLoader import InitLoader
from Init.Registry.InitRegistry import InitRegistry
from Utils.Debug import Logger
# ...
if __name__ == '__main__':
    # ...
    InitLoader.load()

是否有可能以更优雅的方式做到这一点并避免违反 pep8 ?

附:如果我需要分享更多代码,请告诉我

UPD:我的所有类都在单独的文件中声明

这是预加载器:

from Typings.Abstract.AbstractLoader import AbstractLoader
from Init.Registry.InitRegistry import InitRegistry
from Config.Init.configs import main_config


class InitPreLoader(AbstractLoader):

    @staticmethod
    def load(**kwargs):
        InitRegistry.main_config = main_config

这是注册表(我存储所有初始化数据的地方):

from Typings.Abstract.AbstractRegistry import AbstractRegistry


class InitRegistry(AbstractRegistry):

    main_config = None

    login_server = None

    world_server = None

    world_observer = None

    identifier_region_map = None

    region_octree_map = None

所有类的父类(AbstractRegistry除外)是AbstractBase类(它包含mixin):

from abc import ABC

from Config.Mixins.ConfigurableMixin import ConfigurableMixin


class AbstractBase(ConfigurableMixin, ABC):
    pass

此 mixin 适用于来自 InitRegistrymain_config。 此外,在调用 PreLoader 的 load 之后,我使用我的 InitLoader.load() 加载剩余数据(参见第一个代码快照):

from Typings.Abstract.AbstractLoader import AbstractLoader
from Init.Registry.InitRegistry import InitRegistry
from Server.Init.servers import login_server, world_server
from World.Observer.Init.observers import world_observer
from World.Region.Init.regions import identifier_region_map, region_octree_map


class InitLoader(AbstractLoader):

    @staticmethod
    def load(**kwargs):
        InitRegistry.login_server = login_server
        InitRegistry.world_server = world_server
        InitRegistry.world_observer = world_observer
        InitRegistry.identifier_region_map = identifier_region_map
        InitRegistry.region_octree_map = region_octree_map

【问题讨论】:

  • 您能提供更多信息吗? InitPreLoader 持有什么,load 方法做/返回什么? WorldManagerInitLoader 等如何消费 InitPreLoader 提供的任何东西?所有这些类都在您的主代码中实例化了吗?
  • @jfaccioni 感谢您的回复,请查看更新后的问题
  • 我认为您有充分的理由解释为什么要使用类作为数据存储而不是字典。为什么你需要像InitPreLoader 这样的类,它的唯一功能是修改另一个类的类属性,从另一个文件加载,使用来自另一个文件的值?为什么不创建类的实例并将它们传递给代码(封装),而不仅仅是使用静态方法和类变量?抱歉,我的意思不是听起来刺耳,但感觉太复杂了(从我所看到的情况来看)。
  • 也许您可以将其发布到 softwareengineering.stackexchange.comcodereview.stackexchange.com 以获得一些见解。
  • @jfaccioni 感谢您的审查。使用类的唯一原因是一致性。我想要无处不在的类,其中数据动态构建或执行某些操作。我使用字典,但仅用于常量。我的配置存储在 .yml 中,因为我在使用前加载并解析了这个 yml 文件,所以我使用类。

标签: python python-3.x python-import pep8


【解决方案1】:

好吧,现在我找到了解决方案:我将from Init.Loaders.InitPreLoader import InitPreLoader 移动到单独的文件并在那里调用InitPreLoader.load()。但我不喜欢这个解决方案,因为我的 PyCharm IDE 将其突出显示为未使用的导入:

import Init.Init.preloader
from World.WorldManager import WorldManager
# ...

也许可以改进这个解决方案?或者也许存在另一个(更优雅的)解决方案?

【讨论】:

    猜你喜欢
    • 2014-01-21
    • 2021-03-28
    • 2020-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多