简体   繁体   English

如何导入名称中包含点的包中的所有模块?

[英]How do I import all modules in a package that contains a dot in its name?

This linked answer tells me how to import a single module with a dot in its name, but how do I import all modules from a package with a dot in its name: 这个链接的答案告诉我如何导入名称中带有点的单个模块 ,但是如何从名称中包含点的包中导入所有模块:

from package.with.dot.in.name import *

where my files look something like: 我的文件看起来像这样的地方:

package.with.dot.in.name/
    __init__.py
    module_1.py
    module_2.py

I know that having dots in a package name is wrong. 我知道在包名中有点是错误的。 It's there because Sikuli requires your "project" to be named "{project}.sikuli". 它就在那里因为Sikuli要求你的“项目”被命名为“{project} .sikuli”。

Based on this answer and some of the comments, I was able to do: 基于这个答案和一些评论,我能够做到:

name = 'package.with.dot.in.name'
pathname, description = imp.find_module(name)[1:]
package = imp.load_module(name, None, pathname, description)
locals().update(package.__dict__)

While in no way I would encourage this behavior, you can do this by updating your locals() via a reference to it with the internal dictionary of attributes from the module you imported: 虽然我绝不会鼓励这种行为,但你可以通过使用你导入的模块的内部属性字典来引用它来更新你的locals()

>>> r = __import__('requests')
>>> l = locals()
>>> l.update(r.__dict__)
>>> locals()['cookies']
<module 'requests.cookies' from '/usr/local/lib/python2.7/site-packages/requests/cookies.pyc'>

Or, put another way: 或者,换句话说:

>>> cookies
<module 'requests.cookies' from '/usr/local/lib/python2.7/site-packages/requests/cookies.pyc'>

Edit: using Jace's self-answer below, the following will work for filenames with dots: 编辑:使用下面的Jace自我答案,以下内容适用于带点的文件名:

name = 'package.with.dot.in.name'
pathname, description = imp.find_module(name)[1:]
package = imp.load_module(name, None, pathname, description)
locals().update(package.__dict__)

Well, like almost everything in Python, the import system is hack-able. 嗯,就像Python中的几乎所有东西一样,导入系统是可以破解的。 You just need to create a custom loader and register it at sys.meta_path (for details see PEP 302 ). 您只需要创建一个自定义加载器并在sys.meta_path注册它(有关详细信息,请参阅PEP 302 )。

Lets say you want to hack the import system in order to load "foo.bar" if you import "foo_dot_bar": 让我们假设您想破解导入系统,以便在导入“foo_dot_bar”时加载“foo.bar”:

# search folder "foo.bar" and load it as a package
from foo_dot_bar import *     

Be warned: this is just a starting point for you, it is not a fully tested solution; 请注意:这只是一个起点,它不是一个经过全面测试的解决方案; in fact it is way beyond my wizardry level! 事实上它超越了我的巫术水平!

# stupid_dot_importer.py
import os
import imp
import sys

class StupidDotPackageLoader(object):
    @staticmethod
    def _get_real_name(name):
        return ".".join(name.split('_dot_'))
    def find_module(self, name, path=None):
        try:
            imp.find_module(self._get_real_name(name))
        except ImportError:
            return None
        return self
    def load_module(self, name):
        _, pathname, description = imp.find_module(self._get_real_name(name))
        return imp.load_module(self._get_real_name(name), None, pathname, description)

Suppose you have the following structure: 假设您具有以下结构:

foo.bar
   |
   +--- __init__.py 
   |
   +--- module1.py
   |
   +--- module2.py

And: 和:

$ cat foo.bar/__init__.py
from module1 import *
from module2 import *

$ cat foo.bar/module1.py
foo = 'bar'

$ cat foo.bar/module2.py
spam = 'eggs'

Then magic: 然后魔术:

>>> from stupid_dot_importer import *
>>> sys.meta_path = [StupidDotPackageLoader()]
>>> from foo_dot_bar import *
>>> foo
'bar'
>>> spam
'eggs'
>>>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM