[英]Should I always use the most pythonic way to import modules?
我正在为pygame开发一个小型游戏框架,在该框架上我希望实现基本代码以快速启动新项目。 这将是一个模块,无论谁使用,都应仅创建一个带有子文件夹的子文件夹,用于存放精灵类,地图,关卡等。我的问题是,我的框架模块应如何加载这些客户端模块? 我正在考虑对其进行设计,以便开发人员可以将目录名称传递给主对象,例如:
game = Game()
game.scenarios = 'scenarios'
然后游戏会将“场景”追加到sys.path并使用__import__()
。 我已经测试了而且可以用 。 但是后来我研究了一下,看是否在python中已经有一些自动加载器,所以我可以避免重写它,而我发现了这个问题Python模块自动加载器? 基本上,不建议在python中使用自动加载器,因为“显式优于隐式”和“可读性”。
这样,我认为,我应该强迫我的模块的用户手动导入他/她的每个模块,并将它们传递给游戏实例,例如:
import framework.Game
import scenarios
#many other imports
game = Game()
game.scenarios = scenarios
#so many other game.whatever = whatever
但这对我来说并不好,不那么舒服。 看,我曾经使用过php,我喜欢它与自动加载器一起工作的方式。 因此,第一个示例可能会崩溃或出现麻烦,还是不是“ pythonic”?
注意: 这不是Web应用程序
我不会考虑让库从我当前的路径或模块好的样式中导入内容。 相反,我只希望库从两个地方导入:
从全局模块空间绝对导入,就像您使用pip
安装的东西一样。 如果库执行此操作,则还必须在其install_requires=[]
列表中找到该库。
从自身内部的相对进口。 如今,这些已明确从中导入.
:
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()
类,该类实现某个接口以提供sprites
, maps
等。原因是:Sprites和Maps通常存储在单独的文件中: 您绝对不想做的是查看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的情况scenarios=
使用(例如,用于方形默认贴图和一些彩色默认纹理)
from . import contrib
class Game()
def __init__(self, ..., scenarios=None, ...):
if scenarios is None:
scenarios = contrib.scenarios
self.scenarios = scenarios
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.