mik*_*725 63 python python-import
我可能遗漏了一些显而易见的东西但无论如何
当您os在python中导入包时,您可以使用任何子模块/子包.例如,这有效:
>>> import os
>>> os.path.abspath(...)
Run Code Online (Sandbox Code Playgroud)
但是我有自己的包,其结构如下:
FooPackage/
__init__.py
foo.py
Run Code Online (Sandbox Code Playgroud)
这里相同的逻辑不起作用:
>>> import FooPackage
>>> FooPackage.foo
AttributeError: 'module' object has no attribute 'foo'
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
Ben*_*Ben 64
导入时FooPackage,Python会搜索PYTHONPATH上的目录,直到找到调用的文件FooPackage.py或名为FooPackage包含调用文件的目录__init__.py.然而,在找到一个包目录,它并不能再扫描该目录,并自动导入所有.py文件.
这种行为有两个原因.第一个是导入模块执行Python代码,这可能需要时间,内存或副作用.所以你可能想要导入a.b.c.d而不必导入所有庞大的包a.由包装设计者决定是否__init__.py明确地导入其模块和子包以使它们始终可用,或者是否让客户端程序选择加载的内容.
第二个是更微妙,也是一个showstopper.如果没有显式的import语句(在FooPackage/__init__.py客户端程序中或在客户端程序中),Python不一定知道它应该导入的名称foo.py.在(如在Windows中使用)不区分大小写的文件系统,这可能是一个名为模块foo,Foo, FOO,fOo,foO,FoO,FOo,或fOO.所有这些都是有效的,不同的Python标识符,因此Python只是没有足够的信息来自文件来知道你的意思.因此,为了在所有系统上表现一致,它需要在某处明确导入语句以澄清名称,即使在可获得完整案例信息的文件系统上也是如此.
Rob*_*ers 38
您需要导入子模块:
import FooPackage.foo
Run Code Online (Sandbox Code Playgroud)
你在做什么是寻找foo在FooPackage/__init__.py.你可以通过put import FooPackage.foo as foo(或from . import foo)来解决它FooPackage/__init__.py,然后Python就能在foo那里找到它.但我建议使用我的第一个建议.
需要解决一些重要的误解,特别是术语.首先,通常,当您认为导入packagepython时,实际导入的是a module.package当您考虑文件系统子结构时,您应该使用该术语来帮助您组织代码.但是从代码的角度来看,无论何时导入package,Python都会将其视为模块.所有包都是模块.并非所有模块都是包.具有该__path__属性的模块被视为包.
你可以检查那os是一个模块.要确认这一点,您可以:
import os
print(type(os)) # will print: <type 'module'>
Run Code Online (Sandbox Code Playgroud)
在你的例子中,当你这样做时import FooPackage,它FooPackage也被视为一个模块,并且它的属性(函数,类等)被定义为__init__.py.由于你__init__.py是空的,所以找不到foo.
在import语句之外,您不能使用'.'符号来处理模块内部的模块.如果module在目标父代的包__init__.py文件中导入了a,则会发生唯一的异常.为了说清楚,让我们在这里做一些例子:
考虑你的原始结构:
FooPackage/
__init__.py
foo.py
Run Code Online (Sandbox Code Playgroud)
情况1:__ init__.py是一个空文件
#FooPackage imported as a module
import FooPackage
#foo is not a name defined in `__init__.py`. Error
FooPackage.foo
#FooPackage.foo imported as a module
import FooPackage.foo
#Error, foo has not been imported. To be able to use foo like this,
#you need to do: import FooPackage.foo as foo
foo.anything
#Not error, if anything is defined inside foo.py
FooPackage.foo.anything
Run Code Online (Sandbox Code Playgroud)
案例2:__ init__.py中有一行import foo:
import FooPackage
#Now this is good. `foo` is sort of considered to be an attribute of
#FooPackage
FooPackage.foo
Run Code Online (Sandbox Code Playgroud)
现在,假设foo不再是a module,而是function你定义的__init__.py.如果你这样做import FooPackage.foo,它会抛出一个错误,说这foo不是一个模块.
| 归档时间: |
|
| 查看次数: |
85487 次 |
| 最近记录: |