如何使用从一个模块加载到另一个模块的主程序的字典? [英] How to use a Dictionary loaded from one module into the main program from another module loaded after that?

查看:190
本文介绍了如何使用从一个模块加载到另一个模块的主程序的字典?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我使用一个函数来读取一个模块中的文件的内容:

  def get_objectstore():

with open(os.getcwd()+\\\data.store,rb)as infile:
objA = cPickle.load(infile)
objectstore = eval((str(objA))。translate(string.maketrans(coder,alpha)))
return objectstore

,我从我的主程序调用这个函数,如下所示:

  from main_vars import get_objectstore 

objectstore = get_objectstore()

现在objectstore具有我的程序使用的所有图像和声音。如何使用

  objectstore 

在加载到主程序的所有其他模块中。

解决方案


如何在加载到主程序的所有其他模块中使用 objectstore


这是您可以可以做的事情之一,但几乎肯定不应该 ...所以首先我会解释一下,然后解释为什么不。






如果您希望在每个模块中直接提供某些内容,而无需在每个模块中导入,就像它是内置的...答案是将其添加到内建中。那么,你该怎么做呢?



从技术上来说,没有保证安全的方法,但实际上,我相信monkeypatching builtins 模块在每个主要实现的每个版本中工作。所以:

  import builtins 
builtins.objectstore = objectstore
pre>

请注意,在Python 2.x中,该模块称为 __ builtin __ ,但工作方式相同。






这在几种情况下不起作用,例如,内部代码由 exec 与自定义全局变量提供了一个自定义的 __ builtins __ 。如果你需要处理这个...好吧,你不能轻易地处理它。但是,如果你只关心CPython(而且我认为PyPy,而不是Jython,而且我不知道Iron ...)?在CPython中,保证每个全局环境,即使为编译, exec 等创建的环境将包含一些名为 __ builtins __ 的内容是该环境的内置命令,或者一些名称空间是环境内置命令的对象。如果没有内建的,或者您正在查看内建模块本身的全局环境,可能会丢失。所以,你可以这样写:

  try:
__builtins __ ['objectstore'] = objectstore
except AttributeError:
__builtins __。objectstore = objectstore

(这不处理你在内置函数内部运行代码,因为...我不知道你想在那里做什么,老实说。)



当然这很丑。这可能是有意义的。






现在,你为什么不想这样做?



嗯,首先,它使你的代码难以阅读。任何看着你的代码的人都无法知道在哪里定义了 objectstore ,除了搜索当前模块中甚至没有被引用的一些完全不相关的模块。



另外,它可能会导致难以调试的问题。如果以后更改哪些模块的列表导入哪些其他模块,那么依赖于 objectstore 的模块可能会在修补之前运行,因此会失败。



另外,事实上,实际上没有记录你可以使用内嵌函数,或者这样做会影响内置环境,这是一个很好的迹象,这不是你应该依赖的。



最好做出明确的内容。将$ code> objectstore 作为每个其他模块从中导入的某个模块的全局模块。那么就可以立即清楚发生了什么,甚至是粗略的一瞥。



例如,为什么不添加 objectstore = get_objectstore() mainvars ,然后每个模块都从mainvars import objectstore 执行?或者也许你甚至想要使它成为一个单例,所以任何人都可以调用 get_objectstore(),并知道他们都会得到一个单独的共享值。不知道你想要完成什么,很难建议一个最佳的解决方案。所有我可以肯定地说,使得内置的跨模块全局的 objectstore 不太可能成为几乎可能要完成的任何事情的最佳解决方案。 / p>

If I use a function to read the contents of a file in one module:

def get_objectstore():

    with open(os.getcwd() + "\\data.store", "rb") as infile:
        objA = cPickle.load(infile)
        objectstore = eval((str(objA)).translate(string.maketrans(coder, alpha)))
    return objectstore 

and I call this function from my main program like this:

from main_vars import get_objectstore

objectstore=get_objectstore()

now objectstore has all images and sound used by my program. How can I use

objectstore

in all other modules loaded into the main program.

解决方案

How can I use objectstore in all other modules loaded into the main program.

This is one of those things that you can do, but almost certainly shouldn't… so first I'll explain how, then explain why not.


If you want something to be directly available in every module, without having to import it in each module, just as if it were a builtin… the answer is to add it to the builtins. So, how do you do that?

Well, technically, there's no guaranteed safe way to do it, but practically, I believe monkeypatching the builtins module works in every version of every major implementation. So:

import builtins
builtins.objectstore = objectstore

Note that in Python 2.x, the module is called __builtin__, but works the same way.


This doesn't work in a few cases, e.g., inside code being run by an exec with a custom globals that provides a custom __builtins__. If you need to handle that… well, you can't handle it portably. But what if you only care about CPython (and I think PyPy, but not Jython, and I don't know about Iron…)? In CPython, it's guaranteed that every global environment, even the ones created for compile, exec, etc., will contain something named __builtins__ that's either the builtin dict for that environment, or some object whose namespace is the builtin dict for the environment. If there are no builtins at all, or you're looking at the global environment for the builtins module itself, it may be missing. So, you can write this:

try:
    __builtins__['objectstore'] = objectstore
except AttributeError:
    __builtins__.objectstore = objectstore

(That doesn't handle the case where you're running code inside the builtins namespace itself, because… I'm not sure what you'd want to do there, to be honest.)

Of course that's ugly. That's probably on purpose.


Now, why don't you want to do that?

Well, for one thing, it makes your code a lot harder to read. Anyone looking at your code can't tell where objectstore was defined, except by searching some completely unrelated module that isn't even referenced in the current module.

For another, it can lead to problems that are hard to debug. If you later change the list of which modules import which other modules, some module that depends on objectstore being patched in may run before it's been patched in and therefore fail.

Also, the fact that it's not actually documented that you can monkeypatch builtins, or that doing so affects the builtin environment, is a good sign that it's not something you should be relying on.

It's better to make what you're doing explicit. Have objectstore be a module global for some module that every other module imports from. Then it's immediately clear what's happening, on even a cursory glance.

For example, why not add that objectstore = get_objectstore() to mainvars, and then have every module do from mainvars import objectstore? Or maybe you even want to make it a singleton, so it's safe for anyone to call get_objectstore() and know that they'll all get back a single, shared value. Without knowing exactly what you're trying to accomplish, it's hard to suggest a best solution. All I can say for sure is that making objectstore a builtin-like cross-module global is very unlikely to be the best solution for almost anything you might be trying to accomplish.

这篇关于如何使用从一个模块加载到另一个模块的主程序的字典?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆