使用eclipse创建包以及子包

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用eclipse创建包以及子包相关的知识,希望对你有一定的参考价值。

参考技术A 使用eclipse创建包以及子包,是件很容易的事情,但是如果你希望创建的包如下面这种情况恐怕不太容易

上图展示出层级的样式,但是我使用的eclipes却没有那样展示,而是以一种并行的方式排列,虽然它们在命名上体现了包含关系,但是我不能确定,后来在网上查找,但苦于这种情况不太好描述,也没有什么明确的结果,我推测上图那种展示情况应该是比较早版本的eclipse的展示情况。

另外一种情况,比如你创建了一个包 com.myhouse.mybed,这时候你想在com.myhouse 这个包下创建一个新的类或者接口文件,你可能会发现当你要创建com.myhouse,这个包的时候,会提示你该包已经存在,其实com.myhouse.mybed这个包就像一个文件夹路径,也就是说创建一个包之后,其父包也都已经存在了。所以,你无需再创建com.myhouse, 而是直接创建类或者接口的时候,修改其存储在的包名为com.myhouse就行了。

Python 只导入一个子包,没有其他子包

【中文标题】Python 只导入一个子包,没有其他子包【英文标题】:Python import one subpackage without others 【发布时间】:2016-01-31 19:54:57 【问题描述】:

我有以下包结构

package
    __init__.py
    sub1
        __init__.py
        foo.py      # Contains class Foo
    sub2
        __init__.py
        bar.py      # Contains class Bar

我希望能够只使用import package 并拥有package.Foopackage.Bar,即我想让子包对用户透明。

问题是导入 sub2 需要很长时间,而且很多用户根本不关心 sub2 中的内容,只想要 sub1 中的内容。因此,我希望用户能够说import package.sub1from package import sub1 只需 导入 sub1 并跳过 sub2 的导入。

我知道我可以通过包含 package/__init__.py 来实现第一部分

from .sub1 import *
from .sub2 import *

并且将package/sub1/__init__.py 设置为from .foo import Foo,对于sub2 也是如此。但是,即使用户尝试仅导入 package.sub1,这也将始终导入 sub1 和 sub2。

相应地,我可以通过让package/__init__.py 为空并使用与上面相同的sub1/__init__.py 来实现第二部分。但是,仅仅说import package 不会加载 sub1 或 sub2,因此用户必须显式加载它们,然后引用 package.sub1.Foo

理想情况下,一个解决方案在 2.7.10 和 3.5.0 中都适用,但如果两者都不可行,我会接受其中一个。

【问题讨论】:

一个更好的问题是为什么sub2中有一个模块级别的长时间运行代码 所以,事实上,你的问题是:“我希望 import package.sub1import package 做的事情更少,对吧?没有像提前读取字节码这样的奇怪技巧,我认为这是不可能。import A.B 必须首先import A。注意docs.python.org/3.6/library/importlib.html 底部(最后一个代码块,第 15 行),import_module 是一个递归函数。但是,您可以轻松拥有第三个子包,package.everything ,这将真正将sub1sub2 导入到同一个命名空间中。 @Veky:这确实是我最终所做的(嗯,package.all,但足够接近) .all 是我的第一个想法,但我决定反对它,因为它 a) 会引起与 package.__all__ 的错误关联,并且 b) 对于你不想鼓励的东西来说有点太短了人们去做(一个有吸引力的麻烦)。 【参考方案1】:

您可以将快捷方式添加到模块的__init__.py

package/__init__.py

__all__ = [
    ... add everything you want to be listed for this module
    'Foo',
    'Bar',
    ...
]
from package.sub1.foo import Foo
from package.sub2.bar import Bar

现在你应该可以打电话了:

from package import Bar

【讨论】:

这会在import package 之后启用package.Bar,但它不处理问题的“延迟导入”部分。【参考方案2】:

LazyLoader 类正是针对这种情况提供的:在实际使用模块时推迟加载模块,而不是在导入时。

要构建一个惰性加载器,您可以按照文档中的示例进行操作:

suffixes = importlib.machinery.SOURCE_SUFFIXES
loader = importlib.machinery.SourceFileLoader
lazy_loader = importlib.util.LazyLoader.factory(loader)
finder = importlib.machinery.FileFinder(path, [(lazy_loader, suffixes)])

然后您可以使用finder.find_spec 获取模块的规格并将结果传递给Loader.create_module 以加载它。

仅对一个模块手动执行此操作有点麻烦。

请注意,搜索“lazy import python”你会发现相当多的解决方案,它们各有优缺点,其中一些在 python2.x 中运行。但是上面的LazyLoader 类是python3.5+中的官方方法

【讨论】:

我无法让它从子包中实际加载内容。如果sub2/__init__.pyfrom .bar import Bar,它返回ImportError: No module named 'package.bar' 如果它使用绝对导入,我得到ValueError: module object for 'package.sub2' substituted in sys.modules during a lazy load 这似乎也只有sub2 下的符号,所以我仍然不得不说package.sub2.Bar而不仅仅是package.Bar 对于将来看到这个的任何人,如果你(像我一样)不能让惰性加载器工作,我的解决方案是只拥有一个 package.all(或者 .everything,如果你愿意)导入所有内容,而***包不导入任何内容。有关更多讨论,请参阅有关问题的 cmets

以上是关于使用eclipse创建包以及子包的主要内容,如果未能解决你的问题,请参考以下文章

eclipse在包下新建子包

Eclipse中的分层包结构

如何在 Eclipse 项目资源管理器中的包内创建子包

eclipse 包与子包的视图显示方式切换

如何在 Eclipse 中将包查看为文件夹结构

JavaSE知识-11(Eclipse使用以及Object类型)