我应该一直使用最python的方式来导入模块吗?

2024-06-03 13:30:38 发布

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

我正在用pygame为游戏制作一个小框架,我希望在这个框架上实现基本代码,以便快速启动新项目。这将是一个模块,谁使用应该只是创建一个文件夹与子文件夹的精灵类,地图,水平等。 我的问题是,我的框架模块应该如何加载这些客户机模块?我正在考虑设计它,这样开发人员就可以将目录的名称传递给主对象,比如:

game = Game()
game.scenarios = 'scenarios'

然后游戏将附加“场景”到系统路径使用__import__()我已经测试过了,它可以工作了。 但是后来我做了更多的研究,看看python中是否已经有一些自动加载器,这样我就可以避免重写它,我发现了这个问题Python modules autoloader? 基本上,不建议在python中使用autoloader,因为“显式优于隐式”和“可读性计数”。你知道吗

这样,我想,我应该强制我的模块的用户手动导入他/她的每个模块,并将它们传递给游戏实例,如:

import framework.Game
import scenarios
#many other imports
game = Game()
game.scenarios = scenarios
#so many other game.whatever = whatever

但这看起来不太好,不太舒服。看,我习惯于使用php,我喜欢它使用autoloader的方式。 所以,第一个例子可能会崩溃或者遇到一些麻烦,或者它不是“pythonic”?你知道吗

注意:这不是web应用程序


Tags: 模块项目代码import文件夹框架game游戏
1条回答
网友
1楼 · 发布于 2024-06-03 13:30:38

我不会考虑让一个库从我当前的路径或模块中导入东西。相反,我只希望库从两个地方导入:

  1. 从全局模块空间进行绝对导入,就像您使用pip安装的东西一样。如果库执行此操作,则还必须在其install_requires=[]列表中找到此库

  2. 从内部的相对进口。现在这些都是从.显式导入的:

    from . import bla
    from .bla import blubb
    

这意味着向当前作用域传递本地对象或模块必须始终显式进行:

from . import scenarios
import framework

scenarios.sprites  # attribute exists
game = framework.Game(scenarios=scenarios)

这允许您模拟scenarios模块:

import types
import framework

# a SimpleNamespace looks like a module, as they both have attributes
scenarios = types.SimpleNamespace(sprites='a', textures='b')
scenarios.sprites  # attribute exists
game = framework.Game(scenarios=scenarios)

您还可以实现一个framework.utils.Scenario()类,该类实现一个特定的接口来提供spritesmaps等。原因是:精灵和贴图通常保存在不同的文件中:您绝对不想做的是查看scenarios__file__属性并开始在其文件中进行猜测。而是实现一个提供统一接口的方法。你知道吗

class Scenario():
    def __init__(self):
        ...

    def sprites(self):
        # optionally load files from some default location
        # If no such things as a default location exists, throw a NotImplemented error
        ...

您的特定于用户的场景将从中派生,并可以选择重载加载方法

import framework.utils
class Scenario(framework.utils.Scenario):
    def __init__(self):
        ...

    def sprites(self):
        # this method *must* load files from location
        # accessing __file__ is OK here
        ...

您还可以让framework提供自己的framework.contrib.scenarios模块,在没有使用scenarios=关键字arg的情况下使用该模块(即,对于方形默认贴图和一些彩色默认纹理)

from . import contrib

class Game()
    def __init__(self, ..., scenarios=None, ...):
        if scenarios is None:
            scenarios = contrib.scenarios
        self.scenarios = scenarios

相关问题 更多 >