Jor*_*ril 508 python python-module python-import
想象一下这个目录结构:
app/
__init__.py
sub1/
__init__.py
mod1.py
sub2/
__init__.py
mod2.py
Run Code Online (Sandbox Code Playgroud)
我正在编码mod1,我需要从中导入一些东西mod2.我该怎么办?
我尝试了from ..sub2 import mod2但是我得到了"尝试非包装中的相对导入".
我google了一下,但发现只有" sys.path操纵"黑客.有没有干净的方式?
编辑:我__init__.py的所有人目前都是空的
EDIT2:我想这样做,因为SUB2包含了为子包(共享类sub1,subX等等).
Edit3:我正在寻找的行为与PEP 366中描述的相同(感谢John B)
Joh*_*n B 329
每个人似乎都想告诉你你应该做什么,而不仅仅是回答这个问题.
问题是你通过将mod1.py作为参数传递给解释器来运行模块'__main__'.
从PEP 328:
相对导入使用模块的__name__属性来确定模块在包层次结构中的位置.如果模块的名称不包含任何包信息(例如,它设置为'__main__'),则解析相对导入,就像模块是顶级模块一样,无论模块实际位于文件系统的哪个位置.
在Python 2.6中,他们添加了相对于主模块引用模块的功能. PEP 366描述了这种变化.
更新:根据Nick Coghlan的说法,推荐的替代方法是使用-m开关在包内运行模块.
nos*_*klo 124
main.py
setup.py
app/ ->
__init__.py
package_a/ ->
__init__.py
module_a.py
package_b/ ->
__init__.py
module_b.py
Run Code Online (Sandbox Code Playgroud)
python main.py.main.py 作用: import app.package_a.module_amodule_a.py 不 import app.package_b.module_b或者2或3可以使用: from app.package_a import module_a
只要你有appPYTHONPATH ,那就行了.main.py可能在任何地方.
因此,您编写了一个setup.py将整个应用程序包和子包复制(安装)到目标系统的python文件夹,以及main.py目标系统的脚本文件夹.
Pan*_*aj 122
这是适用于我的解决方案:
我做相对导入 from ..sub2 import mod2
然后,如果我想运行mod1.py然后我转到父目录app并使用python -m开关运行模块as python -m app.sub1.mod1.
相对导入出现此问题的真正原因是相对导入通过获取__name__模块的属性来工作.如果模块正在直接运行,则__name__设置为,__main__并且它不包含有关包结构的任何信息.而且,这就是为什么python抱怨relative import in non-package错误.
因此,通过使用-m开关,您可以向python提供包结构信息,通过它可以成功解析相对导入.
在进行相对导入时,我多次遇到过这个问题.并且,在阅读了之前的所有答案之后,我仍然无法以干净的方式弄清楚如何解决它,而无需在所有文件中放置样板代码.(虽然有些评论非常有用,感谢@ncoghlan和@XiongChiamiov)
希望这可以帮助那些与相对进口问题作斗争的人,因为通过PEP真的不好玩.
les*_*nik 49
"Guido将包中的脚本视为反模式"(拒绝 PEP-3122)
我花了很多时间试图找到解决方案,在Stack Overflow上阅读相关帖子并对自己说"必须有更好的方法!".看起来没有.
Ром*_*ьев 33
这是100%解决的:
在app/main.py中导入设置/ local_setting.py:
main.py:
import sys
sys.path.insert(0, "../settings")
try:
from local_settings import *
except ImportError:
print('No Import')
Run Code Online (Sandbox Code Playgroud)
iEl*_*ric 25
def import_path(fullpath):
"""
Import a file with full path specification. Allows one to
import from anywhere, something __import__ does not do.
"""
path, filename = os.path.split(fullpath)
filename, ext = os.path.splitext(filename)
sys.path.append(path)
module = __import__(filename)
reload(module) # Might be out of date
del sys.path[-1]
return module
Run Code Online (Sandbox Code Playgroud)
我正在使用此代码段从路径导入模块,希望有所帮助
suh*_*lvs 21
nosklo's用例子解释答案
注意:所有__init__.py文件都是空的.
main.py
app/ ->
__init__.py
package_a/ ->
__init__.py
fun_a.py
package_b/ ->
__init__.py
fun_b.py
Run Code Online (Sandbox Code Playgroud)
def print_a():
print 'This is a function in dir package_a'
Run Code Online (Sandbox Code Playgroud)
from app.package_a.fun_a import print_a
def print_b():
print 'This is a function in dir package_b'
print 'going to call a function in dir package_a'
print '-'*30
print_a()
Run Code Online (Sandbox Code Playgroud)
from app.package_b import fun_b
fun_b.print_b()
Run Code Online (Sandbox Code Playgroud)
如果你运行$ python main.py它返回:
This is a function in dir package_b
going to call a function in dir package_a
------------------------------
This is a function in dir package_a
Run Code Online (Sandbox Code Playgroud)
from app.package_b import fun_b from app.package_a.fun_a import print_a所以文件夹中的文件package_b使用文件夹中的文件package_a,这就是你想要的.对??
Gar*_*erg 12
不幸的是,这是一个sys.path hack,但它运行得很好.
我在另一层遇到了这个问题:我已经有了一个指定名称的模块,但它是错误的模块.
我想做的是以下(我正在使用的模块是module3):
mymodule\
__init__.py
mymodule1\
__init__.py
mymodule1_1
mymodule2\
__init__.py
mymodule2_1
import mymodule.mymodule1.mymodule1_1
Run Code Online (Sandbox Code Playgroud)
请注意,我已经安装了mymodule,但在我的安装中我没有"mymodule1"
我会得到一个ImportError,因为它试图从我安装的模块导入.
我试图做一个sys.path.append,但是没有用.什么工作是sys.path.insert
if __name__ == '__main__':
sys.path.insert(0, '../..')
Run Code Online (Sandbox Code Playgroud)
这样的黑客,但让一切工作!所以请记住,如果您希望您的决定覆盖其他路径,那么您需要使用sys.path.insert(0,pathname)来使其工作!这对我来说是一个非常令人沮丧的问题,很多人都说使用sysndpath的"append"函数,但是如果你已经定义了一个模块(我发现它非常奇怪的行为),这不起作用
mil*_*man 10
我想把它放在这里供我自己参考.我知道它不是很好的Python代码,但我需要一个我正在处理的项目的脚本,我想将脚本放在一个scripts目录中.
import os.path
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
Run Code Online (Sandbox Code Playgroud)
正如@EvgeniSergeev在对OP的评论中所说,您可以从以下.py任意位置的文件导入代码:
import imp
foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()
Run Code Online (Sandbox Code Playgroud)
这取自这个SO答案.
看看http://docs.python.org/whatsnew/2.5.html#pep-328-absolute-and-relative-imports。你可以做
from .mod1 import stuff
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
313027 次 |
| 最近记录: |