标签归档:python-import

ImportError:无法导入名称X

问题:ImportError:无法导入名称X

我有四个不同的文件,分别命名为:main,vector,entity和physics。我不会发布所有代码,而只会发布导入代码,因为我认为这就是错误所在。(如果需要,我可以发布更多信息)

主要:

import time
from entity import Ent
from vector import Vect
#the rest just creates an entity and prints the result of movement

实体:

from vector import Vect
from physics import Physics
class Ent:
    #holds vector information and id
def tick(self, dt):
    #this is where physics changes the velocity and position vectors

向量:

from math import *
class Vect:
    #holds i, j, k, and does vector math

物理:

from entity import Ent
class Physics:
    #physics class gets an entity and does physics calculations on it.

然后,我从main.py运行,出现以下错误:

Traceback (most recent call last):
File "main.py", line 2, in <module>
    from entity import Ent
File ".../entity.py", line 5, in <module>
    from physics import Physics
File ".../physics.py", line 2, in <module>
    from entity import Ent
ImportError: cannot import name Ent

我对Python非常陌生,但是已经使用C ++了很长时间。我猜测该错误是由于两次导入实体引起的,一次是在主体中,一次是在物理学中,但是我不知道解决方法。有人可以帮忙吗?

I have four different files named: main, vector, entity and physics. I will not post all the code, just the imports, because I think that’s where the error is. (If you want, I can post more)

Main:

import time
from entity import Ent
from vector import Vect
#the rest just creates an entity and prints the result of movement

Entity:

from vector import Vect
from physics import Physics
class Ent:
    #holds vector information and id
def tick(self, dt):
    #this is where physics changes the velocity and position vectors

Vector:

from math import *
class Vect:
    #holds i, j, k, and does vector math

Physics:

from entity import Ent
class Physics:
    #physics class gets an entity and does physics calculations on it.

I then run from main.py and I get the following error:

Traceback (most recent call last):
File "main.py", line 2, in <module>
    from entity import Ent
File ".../entity.py", line 5, in <module>
    from physics import Physics
File ".../physics.py", line 2, in <module>
    from entity import Ent
ImportError: cannot import name Ent

I am very new to Python but have worked with C++ for a long time. I’m guessing that the error is due to importing entity twice, once in main, and later in physics, but I don’t know a workaround. Can anyone help?


回答 0

您有循环依赖进口。physics.py从定义entity类之前导入,Entphysics尝试导入entity已初始化的类。physicsentity模块中删除对的依赖。

You have circular dependent imports. physics.py is imported from entity before class Ent is defined and physics tries to import entity that is already initializing. Remove the dependency to physics from entity module.


回答 1

虽然您绝对应该避免循环依赖,但可以推迟python中的导入。

例如:

import SomeModule

def someFunction(arg):
    from some.dependency import DependentClass

这(至少在某些情况下)将避免该错误。

While you should definitely avoid circular dependencies, you can defer imports in python.

for example:

import SomeModule

def someFunction(arg):
    from some.dependency import DependentClass

this ( at least in some instances ) will circumvent the error.


回答 2

这是一个循环依赖性。无需对代码进行任何结构修改即可解决。发生此问题的原因是,在vector您要求entity立即可用时,反之亦然。出现此问题的原因是,您要求在模块准备就绪之前通过使用来访问模块的内容from x import y。这基本上与

import x
y = x.y
del x

Python能够检测循环依赖关系并防止导入的无限循环。本质上,所有发生的事情都是为模块创建了一个空的占位符(即,它没有内容)。一旦循环依赖的模块被编译,它将更新导入的模块。这是类似的工作。

a = module() # import a

# rest of module

a.update_contents(real_a)

为了使python能够使用循环依赖关系,您必须import x仅使用样式。

import x
class cls:
    def __init__(self):
        self.y = x.y

由于您不再在顶层引用模块的内容,因此python可以编译模块,而无需实际访问循环依赖项的内容。顶层是指在编译过程中将执行的行,而不是函数的内容(例如y = x.y)。访问模块内容的静态或类变量也会引起问题。

This is a circular dependency. It can be solved without any structural modifications to the code. The problem occurs because in vector you demand that entity be made available for use immediately, and vice versa. The reason for this problem is that you asking to access the contents of the module before it is ready — by using from x import y. This is essentially the same as

import x
y = x.y
del x

Python is able to detect circular dependencies and prevent the infinite loop of imports. Essentially all that happens is that an empty placeholder is created for the module (ie. it has no content). Once the circularly dependent modules are compiled it updates the imported module. This is works something like this.

a = module() # import a

# rest of module

a.update_contents(real_a)

For python to be able to work with circular dependencies you must use import x style only.

import x
class cls:
    def __init__(self):
        self.y = x.y

Since you are no longer referring to the contents of the module at the top level, python can compile the module without actually having to access the contents of the circular dependency. By top level I mean lines that will be executed during compilation as opposed to the contents of functions (eg. y = x.y). Static or class variables accessing the module contents will also cause problems.


回答 3

弄清楚逻辑很重要。出现此问题,因为引用变成死循环。

如果您不想更改逻辑,则可以将导致ImportError的某些import语句放在文件的其他位置,例如结尾。

py

from test.b import b2

def a1():
    print('a1')
    b2()

b.py

from test.a import a1

def b1():
    print('b1')
    a1()

def b2():
    print('b2')

if __name__ == '__main__':
    b1()

您将收到导入错误: ImportError: cannot import name 'a1'

但是,如果我们改变test.b的位置,将b2导入A如下所示:

py

def a1():
    print('a1')
    b2()

from test.b import b2

我们可以得到我们想要的:

b1
a1
b2

To make logic clear is very important. This problem appear, because the reference become a dead loop.

If you don’t want to change the logic, you can put the some import statement which caused ImportError to the other position of file, for example the end.

a.py

from test.b import b2

def a1():
    print('a1')
    b2()

b.py

from test.a import a1

def b1():
    print('b1')
    a1()

def b2():
    print('b2')

if __name__ == '__main__':
    b1()

You will get Import Error: ImportError: cannot import name 'a1'

But if we change the position of from test.b import b2 in A like below:

a.py

def a1():
    print('a1')
    b2()

from test.b import b2

And the we can get what we want:

b1
a1
b2

回答 4

这是一个循环依赖性。我们可以通过在需要的地方使用导入模块或类或函数来解决此问题。如果我们使用这种方法,我们可以修复循环依赖

py

from B import b2
def a1():
    print('a1')
    b2()

py

def b1():
   from A import a1
   print('b1')
   a1()

def b2():
   print('b2')
if __name__ == '__main__':
   b1() 

This is a circular dependency. we can solve this problem by using import module or class or function where we needed. if we use this approach, we can fix circular dependency

A.py

from B import b2
def a1():
    print('a1')
    b2()

B.py

def b1():
   from A import a1
   print('b1')
   a1()

def b2():
   print('b2')
if __name__ == '__main__':
   b1() 

回答 5

我也刚收到这个错误,原因有所不同…

from my_sub_module import my_function

主脚本具有Windows行尾。my_sub_module具有UNIX行结尾。将它们更改为相同可解决此问题。它们还需要具有相同的字符编码。

I just got this error too, for a different reason…

from my_sub_module import my_function

The main script had Windows line endings. my_sub_module had UNIX line endings. Changing them to be the same fixed the problem. They also need to have the same character encoding.


回答 6

如前所述,这是由 循环依赖。尚未提及的是,当您使用Python输入模块并且仅导入用于注释 Types的类时,可以使用 Forward引用

当类型提示包含尚未定义的名称时,该定义可以表示为字符串文字,以便稍后解析。

并删除依赖项(import),例如代替

from my_module import Tree

def func(arg: Tree):
    # code

做:

def func(arg: 'Tree'):
    # code

(注意删除的import语句)

As already mentioned, this is caused by a circular dependency. What has not been mentioned is that when you’re using Python typing module and you import a class only to be used to annotate Types, you can use Forward references:

When a type hint contains names that have not been defined yet, that definition may be expressed as a string literal, to be resolved later.

and remove the dependency (the import), e.g. instead of

from my_module import Tree

def func(arg: Tree):
    # code

do:

def func(arg: 'Tree'):
    # code

(note the removed import statement)


回答 7

不要使用您导入的其他模块的名称来命名当前的python脚本

解决方案:重命名工作的python脚本

例:

  1. 你在工作 medicaltorch.py
  2. 在该脚本中,您具有:应该from medicaltorch import datasets as mt_datasets在哪里medicaltorch安装了模块

将会失败ImportError。只需在1中重命名工作的python脚本即可。

Don’t name your current python script with the name of some other module you import

Solution: rename your working python script

Example:

  1. you are working in medicaltorch.py
  2. in that script, you have: from medicaltorch import datasets as mt_datasets where medicaltorch is supposed to be an installed module

This will fail with the ImportError. Just rename your working python script in 1.


回答 8

在这里还没有看到这个-这真是愚蠢,但是请确保您导入的是正确的变量/函数。

我收到此错误

ImportError:无法导入名称IMPLICIT_WAIT

因为我的变量实际上是IMPLICIT_TIMEOUT

当我将导入更改为使用正确的名称时,我不再收到错误🤦‍♂️

Don’t see this one here yet – this is incredibly stupid, but make sure you’re importing the correct variable/function.

I was getting this error

ImportError: cannot import name IMPLICIT_WAIT

because my variable was actually IMPLICIT_TIMEOUT.

when I changed my import to use the correct name, I no longer got the error 🤦‍♂️


回答 9

如果file1.py要从中导入file2.py并使用此功能:

if __name__ == '__main__':
    # etc

低于in的变量file1.py 不能导入file2.py因为__name__ 不相等 __main__

如果你想从进口的东西file1.pyfile2.py,你需要使用此file1.py

if __name__ == 'file1':
    # etc

如有疑问,请发表assert声明以确定是否__name__=='__main__'

If you are importing file1.py from file2.py and used this:

if __name__ == '__main__':
    # etc

Variables below that in file1.py cannot be imported to file2.py because __name__ does not equal __main__!

If you want to import something from file1.py to file2.py, you need to use this in file1.py:

if __name__ == 'file1':
    # etc

In case of doubt, make an assert statement to determine if __name__=='__main__'


回答 10

跟踪导入错误的一种方法是逐步尝试在每个导入的文件上运行python以跟踪不良文件。

  1. 你会得到类似:

    python ./main.py

    ImportError:无法导入名称A

  2. 然后您启动:

    python ./modules/a.py

    ImportError:无法导入名称B

  3. 然后您启动:

    python ./modules/b.py

    ImportError:无法导入名称C(某些不存在的模块或某些其他错误)

One way to track import error is step by step trying to run python on each of imported files to track down bad one.

  1. you get something like:

    python ./main.py
    

    ImportError: cannot import name A

  2. then you launch:

    python ./modules/a.py
    

    ImportError: cannot import name B

  3. then you launch:

    python ./modules/b.py
    

    ImportError: cannot import name C (some NON-Existing module or some other error)


回答 11

同样与OP没有直接关系,但是在向模块添加新对象后未能重新启动 PyCharm Python控制台也是一种使人非常困惑的好方法ImportError: Cannot import name ...

令人困惑的是,PyCharm 在控制台中自动完成导入,但是导入失败。

Also not directly relevant to the OP, but failing to restart a PyCharm Python console, after adding a new object to a module, is also a great way to get a very confusing ImportError: Cannot import name ...

The confusing part is that PyCharm will autocomplete the import in the console, but the import then fails.


回答 12

在我的情况下,我正在使用Jupyter笔记本工作,而发生这种情况的原因是,从我在工作文件中定义类/函数起,就已经缓存了导入。

我重新启动了Jupyter内核,错误消失了。

In my case, I was working in a Jupyter notebook and this was happening due the import already being cached from when I had defined the class/function inside my working file.

I restarted my Jupyter kernel and the error disappeared.


回答 13

不是专门针对此问询者,但是如果您导入中的类名与您要从中导入的文件中的定义不匹配,则会显示此相同错误。

Not specifically for this asker, but this same error will show if the class name in your import doesn’t match the definition in the file you’re importing from.


回答 14

问题很明显:和模块中的名称之间存在循环依赖关系。entityphysics

无论导入整个模块还是仅导入类,都必须加载名称。

观看此示例:

# a.py
import b
def foo():
  pass
b.bar()
# b.py
import a
def bar():
  pass
a.foo()

它将被编译成:

# a.py
# import b
# b.py
# import a # ignored, already importing
def bar():
  pass
a.foo()
# name a.foo is not defined!!!
# import b done!
def foo():
  pass
b.bar()
# done!

稍作更改,我们可以解决此问题:

# a.py
def foo():
  pass
import b
b.bar()
# b.py
def bar():
  pass
import a
a.foo()

它将被编译成:

# a.py
def foo():
  pass
# import b
# b.py
def bar():
  pass
# import a # ignored, already importing
a.foo()
# import b done!
b.bar()
# done!

The problem is clear: circular dependency between names in entity and physics modules.

Regardless of importing the whole module or just a class, the names must be loaded .

Watch this example:

# a.py
import b
def foo():
  pass
b.bar()
# b.py
import a
def bar():
  pass
a.foo()

This will be compiled into:

# a.py
# import b
# b.py
# import a # ignored, already importing
def bar():
  pass
a.foo()
# name a.foo is not defined!!!
# import b done!
def foo():
  pass
b.bar()
# done!

With one slight change we can solve this:

# a.py
def foo():
  pass
import b
b.bar()
# b.py
def bar():
  pass
import a
a.foo()

This will be compiled into:

# a.py
def foo():
  pass
# import b
# b.py
def bar():
  pass
# import a # ignored, already importing
a.foo()
# import b done!
b.bar()
# done!

如何在Python中进行相对导入?

问题:如何在Python中进行相对导入?

想象一下这个目录结构:

app/
   __init__.py
   sub1/
      __init__.py
      mod1.py
   sub2/
      __init__.py
      mod2.py

我正在编码mod1,我需要从中导入一些东西mod2。我该怎么办?

我尝试过,from ..sub2 import mod2但是得到了“未打包的相对导入尝试”。

我四处搜寻,但只发现“ sys.path操纵”骇客。有没有一种干净的方法?


编辑:我所有__init__.py的当前为空

EDIT2:我想这样做,因为SUB2包含了为子包(共享类sub1subX等等)。

Edit3:我要寻找的行为与PEP 366中描述的相同(感谢John B)

Imagine this directory structure:

app/
   __init__.py
   sub1/
      __init__.py
      mod1.py
   sub2/
      __init__.py
      mod2.py

I’m coding mod1, and I need to import something from mod2. How should I do it?

I tried from ..sub2 import mod2 but I’m getting an “Attempted relative import in non-package”.

I googled around but found only “sys.path manipulation” hacks. Isn’t there a clean way?


Edit: all my __init__.py‘s are currently empty

Edit2: I’m trying to do this because sub2 contains classes that are shared across sub packages (sub1, subX, etc.).

Edit3: The behaviour I’m looking for is the same as described in PEP 366 (thanks John B)


回答 0

每个人似乎都想告诉您应该做什么,而不仅仅是回答问题。

问题是您通过将mod1.py作为参数传递给解释器,从而以“ __main__”的身份运行模块。

PEP 328

相对导入使用模块的__name__属性来确定该模块在包层次结构中的位置。如果模块的名称不包含任何包信息(例如,将其设置为“ __main__”),则相对导入将被视为模块是顶级模块,而不论该模块实际位于文件系统上的哪个位置。

在Python 2.6中,他们添加了相对于主模块引用模块的功能。 PEP 366说明了更改。

更新:根据Nick Coghlan的建议,推荐的替代方法是使用-m开关运行软件包中的模块。

Everyone seems to want to tell you what you should be doing rather than just answering the question.

The problem is that you’re running the module as ‘__main__’ by passing the mod1.py as an argument to the interpreter.

From PEP 328:

Relative imports use a module’s __name__ attribute to determine that module’s position in the package hierarchy. If the module’s name does not contain any package information (e.g. it is set to ‘__main__’) then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.

In Python 2.6, they’re adding the ability to reference modules relative to the main module. PEP 366 describes the change.

Update: According to Nick Coghlan, the recommended alternative is to run the module inside the package using the -m switch.


回答 1

这是对我有效的解决方案:

我执行as的相对导入 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确实很有趣。

Here is the solution which works for me:

I do the relative imports as from ..sub2 import mod2 and then, if I want to run mod1.py then I go to the parent directory of app and run the module using the python -m switch as python -m app.sub1.mod1.

The real reason why this problem occurs with relative imports, is that relative imports works by taking the __name__ property of the module. If the module is being directly run, then __name__ is set to __main__ and it doesn’t contain any information about package structure. And, thats why python complains about the relative import in non-package error.

So, by using the -m switch you provide the package structure information to python, through which it can resolve the relative imports successfully.

I have encountered this problem many times while doing relative imports. And, after reading all the previous answers, I was still not able to figure out how to solve it, in a clean way, without needing to put boilerplate code in all files. (Though some of the comments were really helpful, thanks to @ncoghlan and @XiongChiamiov)

Hope this helps someone who is fighting with relative imports problem, because going through PEP is really not fun.


回答 2

main.py
setup.py
app/ ->
    __init__.py
    package_a/ ->
       __init__.py
       module_a.py
    package_b/ ->
       __init__.py
       module_b.py
  1. 你跑python main.py
  2. main.py 确实: import app.package_a.module_a
  3. module_a.py 确实 import app.package_b.module_b

另外2或3可以使用: from app.package_a import module_a

只要您app在PYTHONPATH中具有此功能,便可以使用。main.py可能在那时的任何地方。

因此,您编写了一个setup.py将整个应用程序包和子包复制(安装)到目标系统的python文件夹以及main.py目标系统的脚本文件夹的代码。

main.py
setup.py
app/ ->
    __init__.py
    package_a/ ->
       __init__.py
       module_a.py
    package_b/ ->
       __init__.py
       module_b.py
  1. You run python main.py.
  2. main.py does: import app.package_a.module_a
  3. module_a.py does import app.package_b.module_b

Alternatively 2 or 3 could use: from app.package_a import module_a

That will work as long as you have app in your PYTHONPATH. main.py could be anywhere then.

So you write a setup.py to copy (install) the whole app package and subpackages to the target system’s python folders, and main.py to target system’s script folders.


回答 3

“ Guido将程序包中正在运行的脚本视为反模式”(被拒绝的 PEP-3122

我花了很多时间试图找到解决方案,在Stack Overflow上阅读了相关文章,并对自己说:“一定有更好的方法!”。好像没有。

“Guido views running scripts within a package as an anti-pattern” (rejected PEP-3122)

I have spent so much time trying to find a solution, reading related posts here on Stack Overflow and saying to myself “there must be a better way!”. Looks like there is not.


回答 4

这可以100%解决:

  • 应用/
    • main.py
  • 设置/
    • local_setings.py

在app / main.py中导入settings / local_setting.py:

main.py:

import sys
sys.path.insert(0, "../settings")


try:
    from local_settings import *
except ImportError:
    print('No Import')

This is solved 100%:

  • app/
    • main.py
  • settings/
    • local_setings.py

Import settings/local_setting.py in app/main.py:

main.py:

import sys
sys.path.insert(0, "../settings")


try:
    from local_settings import *
except ImportError:
    print('No Import')

回答 5

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

我正在使用此代码片段从路径导入模块,希望对您有所帮助

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

I’m using this snippet to import modules from paths, hope that helps


回答 6

nosklo's举例说明答案

注意:所有__init__.py文件均为空。

main.py
app/ ->
    __init__.py
    package_a/ ->
       __init__.py
       fun_a.py
    package_b/ ->
       __init__.py
       fun_b.py

app / package_a / fun_a.py

def print_a():
    print 'This is a function in dir package_a'

app / package_b / fun_b.py

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()

main.py

from app.package_b import fun_b
fun_b.print_b()

如果运行,$ 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
  • main.py可以: from app.package_b import fun_b
  • fun_b.py确实 from app.package_a.fun_a import print_a

所以文件夹中的文件package_b使用了文件夹中的文件package_a,这就是您想要的。对??

explanation of nosklo's answer with examples

note: all __init__.py files are empty.

main.py
app/ ->
    __init__.py
    package_a/ ->
       __init__.py
       fun_a.py
    package_b/ ->
       __init__.py
       fun_b.py

app/package_a/fun_a.py

def print_a():
    print 'This is a function in dir package_a'

app/package_b/fun_b.py

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()

main.py

from app.package_b import fun_b
fun_b.print_b()

if you run $ python main.py it returns:

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
  • main.py does: from app.package_b import fun_b
  • fun_b.py does from app.package_a.fun_a import print_a

so file in folder package_b used file in folder package_a, which is what you want. Right??


回答 7

不幸的是,这是一个sys.path hack,但是效果很好。

我在另一层遇到了这个问题:我已经有一个具有指定名称的模块,但这是错误的模块。

我想要做的是以下操作(我正在使用的模块是module3):

mymodule\
   __init__.py
   mymodule1\
      __init__.py
      mymodule1_1
   mymodule2\
      __init__.py
      mymodule2_1


import mymodule.mymodule1.mymodule1_1  

请注意,我已经安装了mymodule,但是在我的安装中我没有“ mymodule1”

而且我会收到一个ImportError,因为它试图从安装的模块中导入。

我试图做一个sys.path.append,但是没有用。起作用的是sys.path.insert

if __name__ == '__main__':
    sys.path.insert(0, '../..')

有点骇客,但一切正常!因此请记住,如果要决定覆盖其他路径,则需要使用sys.path.insert(0,pathname)使其起作用!这对我来说是一个非常令人沮丧的症结所在,有人说要在sys.path中使用“ append”功能,但是如果您已经定义了一个模块,那是行不通的(我发现这是非常奇怪的行为)

This is unfortunately a sys.path hack, but it works quite well.

I encountered this problem with another layer: I already had a module of the specified name, but it was the wrong module.

what I wanted to do was the following (the module I was working from was module3):

mymodule\
   __init__.py
   mymodule1\
      __init__.py
      mymodule1_1
   mymodule2\
      __init__.py
      mymodule2_1


import mymodule.mymodule1.mymodule1_1  

Note that I have already installed mymodule, but in my installation I do not have “mymodule1”

and I would get an ImportError because it was trying to import from my installed modules.

I tried to do a sys.path.append, and that didn’t work. What did work was a sys.path.insert

if __name__ == '__main__':
    sys.path.insert(0, '../..')

So kind of a hack, but got it all to work! So keep in mind, if you want your decision to override other paths then you need to use sys.path.insert(0, pathname) to get it to work! This was a very frustrating sticking point for me, allot of people say to use the “append” function to sys.path, but that doesn’t work if you already have a module defined (I find it very strange behavior)


回答 8

让我将其放在此处以供我自己参考。我知道这不是很好的Python代码,但是我需要一个脚本来处理我正在处理的项目,所以我想将脚本放在scripts目录中。

import os.path
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))

Let me just put this here for my own reference. I know that it is not good Python code, but I needed a script for a project I was working on and I wanted to put the script in a scripts directory.

import os.path
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))

回答 9

正如@EvgeniSergeev在对OP的注释中所说,您可以使用以下.py命令从任意位置的文件导入代码:

import imp

foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()

这是从此SO答案中获取的

As @EvgeniSergeev says in the comments to the OP, you can import code from a .py file at an arbitrary location with:

import imp

foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()

This is taken from this SO answer.


回答 10


回答 11

Python文档中

在Python 2.5中,您可以使用from __future__ import absolute_import指令将导入的行为切换为绝对导入。在将来的版本(可能是Python 2.7)中,此绝对导入行为将成为默认设置。一旦将绝对导入设置为默认设置,import string就将始终找到标准库的版本。建议用户应尽可能多地开始使用绝对导入,因此最好开始编写from pkg import string代码

From Python doc,

In Python 2.5, you can switch import‘s behaviour to absolute imports using a from __future__ import absolute_import directive. This absolute- import behaviour will become the default in a future version (probably Python 2.7). Once absolute imports are the default, import string will always find the standard library’s version. It’s suggested that users should begin using absolute imports as much as possible, so it’s preferable to begin writing from pkg import string in your code


回答 12

我发现将“ PYTHONPATH”环境变量设置为顶层文件夹更容易:

bash$ export PYTHONPATH=/PATH/TO/APP

然后:

import sub1.func1
#...more import

当然,PYTHONPATH是“全局”的,但它并没有给我带来麻烦。

I found it’s more easy to set “PYTHONPATH” enviroment variable to the top folder:

bash$ export PYTHONPATH=/PATH/TO/APP

then:

import sub1.func1
#...more import

of course, PYTHONPATH is “global”, but it didn’t raise trouble for me yet.


回答 13

除了John B所说的,似乎设置__package__变量应该有帮助,而不是更改变量__main__可能会搞砸其他事情。但是据我测试,它并不能完全正常工作。

我遇到了同样的问题sys.path,而据我所知,PEP 328或366都无法完全解决问题,因为两者在一天结束时都需要将包装的标头包括在其中。

我还要提及的是,我没有找到如何格式化应该放入这些变量的字符串的格式。是"package_head.subfolder.module_name"还是什么?

On top of what John B said, it seems like setting the __package__ variable should help, instead of changing __main__ which could screw up other things. But as far as I could test, it doesn’t completely work as it should.

I have the same problem and neither PEP 328 or 366 solve the problem completely, as both, by the end of the day, need the head of the package to be included in sys.path, as far as I could understand.

I should also mention that I did not find how to format the string that should go into those variables. Is it "package_head.subfolder.module_name" or what?


回答 14

您必须将模块的路径附加到PYTHONPATH

export PYTHONPATH="${PYTHONPATH}:/path/to/your/module/"

You have to append the module’s path to PYTHONPATH:

export PYTHONPATH="${PYTHONPATH}:/path/to/your/module/"

从子目录导入文件?

问题:从子目录导入文件?

我的档案tester.py位于/project

/project有一个名为的子目录lib,文件名为BoxTime.py

/project/tester.py
/project/lib/BoxTime.py

我想导入BoxTimetester。我已经试过了:

import lib.BoxTime

结果是:

Traceback (most recent call last):
  File "./tester.py", line 3, in <module>
    import lib.BoxTime
ImportError: No module named lib.BoxTime

任何想法如何BoxTime从子目录导入?

编辑

__init__.py是问题,但不要忘了提及BoxTime作为lib.BoxTime,或使用:

import lib.BoxTime as BT
...
BT.bt_function()

I have a file called tester.py, located on /project.

/project has a subdirectory called lib, with a file called BoxTime.py:

/project/tester.py
/project/lib/BoxTime.py

I want to import BoxTime from tester. I have tried this:

import lib.BoxTime

Which resulted:

Traceback (most recent call last):
  File "./tester.py", line 3, in <module>
    import lib.BoxTime
ImportError: No module named lib.BoxTime

Any ideas how to import BoxTime from the subdirectory?

EDIT

The __init__.py was the problem, but don’t forget to refer to BoxTime as lib.BoxTime, or use:

import lib.BoxTime as BT
...
BT.bt_function()

回答 0

在此处查看Packages文档(第6.4节):http : //docs.python.org/tutorial/modules.html

简而言之,您需要放置一个名为

__init__.py

在“ lib”目录中。

Take a look at the Packages documentation (Section 6.4) here: http://docs.python.org/tutorial/modules.html

In short, you need to put a blank file named

__init__.py

in the “lib” directory.


回答 1

  • 创建一个名为的子目录lib
  • 创建一个名为的空文件lib\__init__.py
  • 在中lib\BoxTime.py,编写如下函数foo()

    def foo():
        print "foo!"
    
  • 在上面目录中的客户机代码中lib,编写:

    from lib import BoxTime
    BoxTime.foo()
    
  • 运行您的客户端代码。你会得到:

    foo!

后来,在Linux中,它看起来像这样:

% cd ~/tmp
% mkdir lib
% touch lib/__init__.py
% cat > lib/BoxTime.py << EOF
heredoc> def foo():
heredoc>     print "foo!"
heredoc> EOF
% tree lib
lib
├── BoxTime.py
└── __init__.py

0 directories, 2 files
% python 
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from lib import BoxTime
>>> BoxTime.foo()
foo!
  • Create a subdirectory named lib.
  • Create an empty file named lib\__init__.py.
  • In lib\BoxTime.py, write a function foo() like this:

    def foo():
        print "foo!"
    
  • In your client code in the directory above lib, write:

    from lib import BoxTime
    BoxTime.foo()
    
  • Run your client code. You will get:

    foo!
    

Much later — in linux, it would look like this:

% cd ~/tmp
% mkdir lib
% touch lib/__init__.py
% cat > lib/BoxTime.py << EOF
heredoc> def foo():
heredoc>     print "foo!"
heredoc> EOF
% tree lib
lib
├── BoxTime.py
└── __init__.py

0 directories, 2 files
% python 
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from lib import BoxTime
>>> BoxTime.foo()
foo!

回答 2

您可以尝试将其插入sys.path

sys.path.insert(0, './lib')
import BoxTime

You can try inserting it in sys.path:

sys.path.insert(0, './lib')
import BoxTime

回答 3

我写下来是因为每个人似乎都建议您必须创建lib目录。

您无需命名子目录lib。你能说出它anything提供你把一个__init__.py进去。

您可以通过在Linux shell中输入以下命令来做到这一点:

$ touch anything/__init__.py 

所以现在您有了以下结构:

$ ls anything/
__init__.py
mylib.py

$ ls
main.py

然后,你可以导入mylibmain.py这样的:

from anything import mylib 

mylib.myfun()

您也可以像这样导入函数和类:

from anything.mylib import MyClass
from anything.mylib import myfun

instance = MyClass()
result = myfun()

您放置在其中的任何变量函数或类__init__.py也可以访问:

import anything

print(anything.myvar)

或像这样:

from anything import myvar

print(myvar)

I am writing this down because everyone seems to suggest that you have to create a lib directory.

You don’t need to name your sub-directory lib. You can name it anything provided you put an __init__.py into it.

You can do that by entering the following command in a linux shell:

$ touch anything/__init__.py 

So now you have this structure:

$ ls anything/
__init__.py
mylib.py

$ ls
main.py

Then you can import mylib into main.py like this:

from anything import mylib 

mylib.myfun()

You can also import functions and classes like this:

from anything.mylib import MyClass
from anything.mylib import myfun

instance = MyClass()
result = myfun()

Any variable function or class you place inside __init__.py can also be accessed:

import anything

print(anything.myvar)

Or like this:

from anything import myvar

print(myvar)

回答 4

您的lib目录是否包含__init__.py文件?

Python用于__init__.py确定目录是否为模块。

Does your lib directory contain a __init__.py file?

Python uses __init__.py to determine if a directory is a module.


回答 5

尝试import .lib.BoxTime。有关更多信息,请参阅PEP 328中的相对导入。

Try import .lib.BoxTime. For more information read about relative import in PEP 328.


回答 6

我这样做基本上涵盖了所有情况(确保您__init__.py在relative / path / to / your / lib / folder中):

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/your/lib/folder")
import someFileNameWhichIsInTheFolder
...
somefile.foo()


示例:
您在项目文件夹中:

/root/myproject/app.py

您在另一个项目文件夹中:

/root/anotherproject/utils.py
/root/anotherproject/__init__.py

您要使用/root/anotherproject/utils.py并调用其中的foo函数。

因此,您在app.py中编写:

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../anotherproject")
import utils

utils.foo()

I do this which basically covers all cases (make sure you have __init__.py in relative/path/to/your/lib/folder):

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/your/lib/folder")
import someFileNameWhichIsInTheFolder
...
somefile.foo()


Example:
You have in your project folder:

/root/myproject/app.py

You have in another project folder:

/root/anotherproject/utils.py
/root/anotherproject/__init__.py

You want to use /root/anotherproject/utils.py and call foo function which is in it.

So you write in app.py:

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../anotherproject")
import utils

utils.foo()

回答 7

__init__.py在子目录/ lib中创建一个空文件 。并在主代码的开头添加

from __future__ import absolute_import 

然后

import lib.BoxTime as BT
...
BT.bt_function()

或更好

from lib.BoxTime import bt_function
...
bt_function()

Create an empty file __init__.py in subdirectory /lib. And add at the begin of main code

from __future__ import absolute_import 

then

import lib.BoxTime as BT
...
BT.bt_function()

or better

from lib.BoxTime import bt_function
...
bt_function()

回答 8

只是这些答案的补充。

如果要从所有子目录导入所有文件,可以将其添加到文件的根目录。

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

然后,您可以简单地从子目录中导入文件,就像这些文件位于当前目录中一样。

工作实例

如果我的项目中有以下目录及其子目录…

.
├── a.py
├── b.py
├── c.py
├── subdirectory_a
   ├── d.py
   └── e.py
├── subdirectory_b
   └── f.py
├── subdirectory_c
   └── g.py
└── subdirectory_d
    └── h.py

我可以将以下代码放入a.py文件中

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

# And then you can import files just as if these files are inside the current directory

import b
import c
import d
import e
import f
import g
import h

换句话说,此代码将抽象出文件来自哪个目录。

Just an addition to these answers.

If you want to import all files from all subdirectories, you can add this to the root of your file.

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

And then you can simply import files from the subdirectories just as if these files are inside the current directory.

Working example

If I have the following directory with subdirectories in my project…

.
├── a.py
├── b.py
├── c.py
├── subdirectory_a
│   ├── d.py
│   └── e.py
├── subdirectory_b
│   └── f.py
├── subdirectory_c
│   └── g.py
└── subdirectory_d
    └── h.py

I can put the following code inside my a.py file

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

# And then you can import files just as if these files are inside the current directory

import b
import c
import d
import e
import f
import g
import h

In other words, this code will abstract from which directory the file is coming from.


回答 9

/project/tester.py

/project/lib/BoxTime.py

下一__init__.py行创建空白文件,直到找到文件

/project/lib/somefolder/BoxTime.py

#lib-需求有两个项目__init__.py,一个名为somefolder的目录 #somefolder有两个项目boxtime.py__init__.py

/project/tester.py

/project/lib/BoxTime.py

create blank file __init__.py down the line till you reach the file

/project/lib/somefolder/BoxTime.py

#lib — needs has two items one __init__.py and a directory named somefolder #somefolder has two items boxtime.py and __init__.py


回答 10

尝试这个:

from lib import BoxTime

try this:

from lib import BoxTime


Python错误“ ImportError:未命名模块”

问题:Python错误“ ImportError:未命名模块”

Python安装在本地目录中。

我的目录树如下所示:

(local directory)/site-packages/toolkit/interface.py

我的代码在这里:

(local directory)/site-packages/toolkit/examples/mountain.py

要运行该示例,我编写python mountain.py,并且在代码中有:

from toolkit.interface import interface

我得到错误:

Traceback (most recent call last):
  File "mountain.py", line 28, in ?
    from toolkit.interface import interface
ImportError: No module named toolkit.interface

我已经检查过了sys.path,这里有目录/site-packages。另外,我__init__.py.bin在toolkit文件夹中有该文件,以向Python指示这是一个软件包。我__init__.py.bin在示例目录中也有一个。

我不知道为什么Python在时找不到文件sys.path。有任何想法吗?可以是权限问题吗?我需要执行许可吗?

Python is installed in a local directory.

My directory tree looks like this:

(local directory)/site-packages/toolkit/interface.py

My code is in here:

(local directory)/site-packages/toolkit/examples/mountain.py

To run the example, I write python mountain.py, and in the code I have:

from toolkit.interface import interface

And I get the error:

Traceback (most recent call last):
  File "mountain.py", line 28, in ?
    from toolkit.interface import interface
ImportError: No module named toolkit.interface

I have already checked sys.path and there I have the directory /site-packages. Also, I have the file __init__.py.bin in the toolkit folder to indicate to Python that this is a package. I also have a __init__.py.bin in the examples directory.

I do not know why Python cannot find the file when it is in sys.path. Any ideas? Can it be a permissions problem? Do I need some execution permission?


回答 0

根据您对orip帖子的评论,我想这是发生了什么:

  1. __init__.py在Windows上进行了编辑。
  2. Windows编辑器添加了一些不可打印的内容,也许是回车符(Windows中的行尾是CR / LF;在Unix中是LF),或者是CTRL-Z(Windows文件末尾)。
  3. 您使用WinSCP将文件复制到Unix框中。
  4. WinSCP认为:“这不是基本文字;我将添加.bin扩展名以指示二进制数据。”
  5. 缺少__init__.py(现在称为__init__.py.bin)意味着python无法将工具包理解为一个包。
  6. __init__.py在适当的目录中创建,一切正常…?

Based on your comments to orip’s post, I guess this is what happened:

  1. You edited __init__.py on windows.
  2. The windows editor added something non-printing, perhaps a carriage-return (end-of-line in Windows is CR/LF; in unix it is LF only), or perhaps a CTRL-Z (windows end-of-file).
  3. You used WinSCP to copy the file to your unix box.
  4. WinSCP thought: “This has something that’s not basic text; I’ll put a .bin extension to indicate binary data.”
  5. The missing __init__.py (now called __init__.py.bin) means python doesn’t understand toolkit as a package.
  6. You create __init__.py in the appropriate directory and everything works… ?

回答 1

是否

(local directory)/site-packages/toolkit

有一个__init__.py

为了使进口步行通过你的目录中的每个目录必须有一个__init__.py文件。

Does

(local directory)/site-packages/toolkit

have a __init__.py?

To make import walk through your directories every directory must have a __init__.py file.


回答 2

我在LPTHW中进行此练习时遇到了非常相似的事情。我永远无法让Python识别出我正在从其调用的目录中有文件。但是我最终能够使它工作。我所做的以及我的建议是尝试以下操作:

(注意:从您的第一篇文章中,我假设您使用的是基于* NIX的计算机,并且正在通过命令行运行,因此此建议是针对性的。自从我运行Ubuntu以来,我就是这样做的。)

1)将目录(cd)更改为文件所在目录上方的目录。在这种情况下,您将尝试运行mountain.py文件,并尝试调用toolkit.interface.py位于单独目录中的模块。在这种情况下,您将转到包含两个文件路径的目录(或换句话说,这两个文件的路径共享的最近目录)。在这种情况下是toolkit目录。

2)在tookit目录中时,在命令行上输入以下代码行:

export PYTHONPATH=.

这会将您的PYTHONPATH设置为“。”,这基本上意味着您的PYTHONPATH现在将在您当前所在目录(甚至更重要的是,您所在目录的子目录分支)中查找所有被调用的文件。因此,它不只是看在你的当前目录,但在所有可在目录中的当前目录)。

3)在上述步骤中设置完PYTHONPATH之后,请从当前目录(该toolkit目录)运行模块。Python现在应该找到并加载您指定的模块。

希望这可以帮助。我自己对此感到非常沮丧。

I ran into something very similar when I did this exercise in LPTHW; I could never get Python to recognise that I had files in the directory I was calling from. But I was able to get it to work in the end. What I did, and what I recommend, is to try this:

(NOTE: From your initial post, I am assuming you are using an *NIX-based machine and are running things from the command line, so this advice is tailored to that. Since I run Ubuntu, this is what I did)

1) Change directory (cd) to the directory above the directory where your files are. In this case, you’re trying to run the mountain.py file, and trying to call the toolkit.interface.py module, which are in separate directories. In this case, you would go to the directory that contains paths to both those files (or in other words, the closest directory that the paths of both those files share). Which in this case is the toolkit directory.

2) When you are in the tookit directory, enter this line of code on your command line:

export PYTHONPATH=.

This sets your PYTHONPATH to “.”, which basically means that your PYTHONPATH will now look for any called files within the directory you are currently in, (and more to the point, in the sub-directory branches of the directory you are in. So it doesn’t just look in your current directory, but in all the directories that are in your current directory).

3) After you’ve set your PYTHONPATH in the step above, run your module from your current directory (the toolkit directory). Python should now find and load the modules you specified.

Hope this helps. I was quite frustrated with this myself.


回答 3

在* nix上,还要确保正确配置了PYTHONPATH,尤其是它具有以下格式:

 .:/usr/local/lib/python

(请注意.:开头,以便它也可以在当前目录中搜索。)

它也可能在其他位置,具体取决于版本:

 .:/usr/lib/python
 .:/usr/lib/python2.6
 .:/usr/lib/python2.7 and etc.

On *nix, also make sure that PYTHONPATH is configured correctly, especially that it has this format:

 .:/usr/local/lib/python

(Mind the .: at the beginning, so that it can search on the current directory, too.)

It may also be in other locations, depending on the version:

 .:/usr/lib/python
 .:/usr/lib/python2.6
 .:/usr/lib/python2.7 and etc.

回答 4

我解决了自己的问题,并将总结出错误的地方和解决方案:

该文件需要完全调用__init__.py。如果扩展名不同(例如在我的情况下),.py.bin则Python无法在目录中移动,因此找不到模块。要编辑文件,您需要使用Linux编辑器,例如vinano。如果您使用Windows编辑器,则会写一些隐藏的字符。

影响它的另一个问题是,我的根目录安装了另一个Python版本,因此,如果有人正在使用python的本地安装,请确保运行程序的Python安装是本地Python。要检查这一点,只需执行which python,然后查看可执行文件是否在您的本地目录中。如果不是,请更改路径,但请确保本地Python目录位于另一个Python目录之前。

I solved my own problem, and I will write a summary of the things that were wrong and the solution:

The file needs to be called exactly __init__.py. If the extension is different such as in my case .py.bin then Python cannot move through the directories and then it cannot find the modules. To edit the files you need to use a Linux editor, such as vi or nano. If you use a Windows editor this will write some hidden characters.

Another problem that was affecting it was that I had another Python version installed by the root, so if someone is working with a local installation of python, be sure that the Python installation that is running the programs is the local Python. To check this, just do which python, and see if the executable is the one that is in your local directory. If not, change the path, but be sure that the local Python directory is before than the other Python.


回答 5

一个简单的解决方案是使用来安装模块,python -m pip install <library-name>而不是pip install <library-name> 在管理员限制的情况下使用sudo

an easy solution is to install the module using python -m pip install <library-name> instead of pip install <library-name> you may use sudo in case of admin restrictions


回答 6

要将目录标记为包,您需要一个名为的文件__init__.py,这有帮助吗?

To mark a directory as a package you need a file named __init__.py, does this help?


回答 7

使用PyCharm(属于JetBrains套件的一部分),您需要将脚本目录定义为Source:
Right Click > Mark Directory as > Sources Root

Using PyCharm (part of the JetBrains suite) you need to define your script directory as Source:
Right Click > Mark Directory as > Sources Root


回答 8

您正在阅读此答案,表明您__init__.py来对地方了,已经安装了所有依赖项,并且仍在获取ImportError

我遇到了类似的问题,除了我的程序在使用PyCharm运行时可以正常运行,但是当我从终端运行时出现上述错误。进一步挖掘之后,我发现PYTHONPATH该项目目录中没有该条目。因此,我将PYTHONPATH每个Import语句设置为在PyCharm上有效,但不能在terminal上使用

export PYTHONPATH=$PYTHONPATH:`pwd`  (OR your project root directory)

使用sys.pathas 的另一种方法是:

import sys
sys.path.insert(0,'<project directory>') OR
sys.path.append('<project directory>')

您可以根据要搜索项目的顺序使用插入/追加。

You are reading this answer says that your __init__.py is in the right place, you have installed all the dependencies and you are still getting the ImportError.

I was facing a similar issue except that my program would run fine when ran using PyCharm but the above error when I would run it from the terminal. After digging further, I found out that PYTHONPATH didn’t have the entry for the project directory. So, I set PYTHONPATH per Import statement works on PyCharm but not from terminal:

export PYTHONPATH=$PYTHONPATH:`pwd`  (OR your project root directory)

There’s another way to do this using sys.path as:

import sys
sys.path.insert(0,'<project directory>') OR
sys.path.append('<project directory>')

You can use insert/append based on the order in which you want your project to be searched.


回答 9

对我来说,那真是愚蠢。我使用来安装该库,pip3 install但正在运行程序python program.py而不是python3 program.py

For me, it was something really stupid. I installed the library using pip3 install but was running my program as python program.py as opposed to python3 program.py.


回答 10

对。您需要包含该__init__.py文件的目录,该文件是用于初始化程序包的文件。在这里,看看这个

__init__.py文件是使Python将目录视为包含包所必需的;这样做是为了防止具有通用名称的目录(例如字符串)无意间隐藏了稍后在模块搜索路径中出现的有效模块。在最简单的情况下,__init__.py可以只是一个空文件,但它也可以为该程序包执行初始化代码或设置__all__变量,如后所述。

Yup. You need the directory to contain the __init__.py file, which is the file that initializes the package. Here, have a look at this.

The __init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, __init__.py can just be an empty file, but it can also execute initialization code for the package or set the __all__ variable, described later.


回答 11

  1. 您必须在与要导入文件相同的目录中拥有文件__ init__.py。
  2. 您不能尝试从PYTHONPATH上配置的2个文件夹中导入具有相同名称的文件。

例如:/ etc / environment

PYTHONPATH = $ PYTHONPATH:/ opt /文件夹1:/ opt /文件夹2

/ opt / folder1 / foo

/ opt / folder2 / foo

并且,如果您尝试导入foo文件,python将不知道您要哪个。

从foo import … >>> importerror:没有名为foo的模块

  1. You must have the file __ init__.py in the same directory where it’s the file that you are importing.
  2. You can not try to import a file that has the same name and be a file from 2 folders configured on the PYTHONPATH.

eg: /etc/environment

PYTHONPATH=$PYTHONPATH:/opt/folder1:/opt/folder2

/opt/folder1/foo

/opt/folder2/foo

And, if you are trying to import foo file, python will not know which one you want.

from foo import … >>> importerror: no module named foo


回答 12

我的两分钱:

在此处输入图片说明

吐:

Traceback (most recent call last):
      File "bash\bash.py", line 454, in main
        import bosh
      File "Wrye Bash Launcher.pyw", line 63, in load_module
        mod = imp.load_source(fullname,filename+ext,fp)
      File "bash\bosh.py", line 69, in <module>
        from game.oblivion.RecordGroups import MobWorlds, MobDials, MobICells, \
    ImportError: No module named RecordGroups

这让我很困惑-遍历各种帖子,暗示了丑陋的syspath hacks(如您所见,我__init__.py在那里)。好吧,事实证明game / oblivion.py和game / oblivion混淆了python,并吐出了相当无用的“没有名为RecordGroups的模块”。我对解决此问题和/或记录此(相同名称)行为的链接感兴趣->编辑(2017.01.24)-看看如果我具有相同名称的模块和软件包怎么办?有趣的是,通常程序包具有优先权,但显然我们的启动程序违反了此规则。

编辑(2015.01.17):我没有提到我们使用此处剖析的自定义启动器

My two cents:

enter image description here

Spit:

Traceback (most recent call last):
      File "bash\bash.py", line 454, in main
        import bosh
      File "Wrye Bash Launcher.pyw", line 63, in load_module
        mod = imp.load_source(fullname,filename+ext,fp)
      File "bash\bosh.py", line 69, in <module>
        from game.oblivion.RecordGroups import MobWorlds, MobDials, MobICells, \
    ImportError: No module named RecordGroups

This confused the hell out of me – went through posts and posts suggesting ugly syspath hacks (as you see my __init__.py were all there). Well turns out that game/oblivion.py and game/oblivion was confusing python which spit out the rather unhelpful “No module named RecordGroups”. I’d be interested in a workaround and/or links documenting this (same name) behavior -> EDIT (2017.01.24) – have a look at What If I Have a Module and a Package With The Same Name? Interestingly normally packages take precedence but apparently our launcher violates this.

EDIT (2015.01.17): I did not mention we use a custom launcher dissected here.


回答 13

Linux:导入的模块位于/usr/local/lib/python2.7/dist-packages中

如果您使用的是用C语言编译的模块,请不要忘了在之后对.so文件进行chmod修改sudo setup.py install

sudo chmod 755 /usr/local/lib/python2.7/dist-packages/*.so

Linux: Imported modules are located in /usr/local/lib/python2.7/dist-packages

If you’re using a module compiled in C, don’t forget to chmod the .so file after sudo setup.py install.

sudo chmod 755 /usr/local/lib/python2.7/dist-packages/*.so

回答 14

就我而言,问题是我链接到debug pythonboost::Python,它要求扩展名是FooLib_d.pyd,而不仅仅是FooLib.pyd; 重命名文件或更新CMakeLists.txt属性可修复该错误。

In my case, the problem was I was linking to debug python & boost::Python, which requires that the extension be FooLib_d.pyd, not just FooLib.pyd; renaming the file or updating CMakeLists.txt properties fixed the error.


回答 15

如果您尝试了上面提供的所有方法但都失败了,则也许您的模块内置模块具有相同的名称。或者,文件夹中存在的同名sys.path模块比模块具有更高的优先级。

要调试,请说出您的from foo.bar import baz抱怨ImportError: No module named bar。更改为import foo; print foo,将显示的路径foo。是您所期望的吗?

如果不是,请重命名foo或使用绝对导入

If you have tried all methods provided above but failed, maybe your module has the same name as a built-in module. Or, a module with the same name existing in a folder that has a high priority in sys.path than your module’s.

To debug, say your from foo.bar import baz complaints ImportError: No module named bar. Changing to import foo; print foo, which will show the path of foo. Is it what you expect?

If not, Either rename foo or use absolute imports.


回答 16

我的问题是,__init__.py实际上需要添加其父目录时,我将带有文件的目录添加到了PYTHONPATH中。

My problem was that I added the directory with the __init__.py file to PYTHONPATH, when actually I needed to add its parent directory.


回答 17

对于所有仍然有此问题的人。我相信Pycharm与进口商品混淆了。对我来说,当我写“从命名空间导入某物”时,前一行用红色下划线标出,表示有错误,但可以。但是,“从.namespace导入某些内容”不会带有下划线,但也无法正常工作。

尝试

try:
    from namespace import something 
except NameError:
    from .namespace import something

To all those who still have this issue. I believe Pycharm gets confused with imports. For me, when i write ‘from namespace import something’, the previous line gets underlined in red, signaling that there is an error, but works. However ”from .namespace import something’ doesn’t get underlined, but also doesn’t work.

Try

try:
    from namespace import something 
except NameError:
    from .namespace import something

回答 18

通过编写修复了我的问题print (sys.path),发现尽管进行了全新安装,python仍在使用过期的软件包。删除这些使python自动使用正确的软件包。

Fixed my issue by writing print (sys.path) and found out that python was using out of date packages despite a clean install. Deleting these made python automatically use the correct packages.


回答 19

就我而言,因为我正在使用PyCharm和PyCharm在项目文件夹中为每个项目创建一个“ venv”,但这只是python的一个迷你环境。尽管您已经在Python中安装了所需的库,但是在您的自定义项目“ venv”中,该库不可用。这是PyCharm中发生“导入错误:没有名为xxxxxx的模块”的真正原因。要解决此问题,必须通过以下步骤将库添加到项目自定义环境中:

  • 在PyCharm中,从菜单“文件”->“设置”
  • 在设置对话框中,项目:XXXProject->项目解释器
  • 点击“添加”按钮,它将显示“可用包”对话框
  • 搜索您的库,单击“安装软件包”
  • 然后,所有需要的软件包将安装在项目自定义“ venv”文件夹中。

设置对话框

请享用。

In my case, because I’m using PyCharm and PyCharm create a ‘venv’ for every project in project folder, but it is only a mini env of python. Although you have installed the libraries you need in Python, but in your custom project ‘venv’, it is not available. This is the real reason of ‘ImportError: No module named xxxxxx’ occurred in PyCharm. To resolve this issue, you must add libraries to your project custom env by these steps:

  • In PyCharm, from menu ‘File’->Settings
  • In Settings dialog, Project: XXXProject->Project Interpreter
  • Click “Add” button, it will show you ‘Available Packages’ dialog
  • Search your library, click ‘Install Package’
  • Then, all you needed package will be installed in you project custom ‘venv’ folder.

Settings dialog

Enjoy.


回答 20

在经历了同样的问题后,我发现我的解决方案是pyc从项目中删除所有文件,似乎这些缓存的文件以某种方式导致了此错误。

我发现最简单的方法是在Windows资源管理器中导航到我的项目文件夹并搜索*.pyc,然后选择所有(Ctrl+ A)并删除它们(Ctrl+ X)。

可能我可以通过删除特定pyc文件来解决问题,但我从未尝试过

After just suffering the same issue I found my resolution was to delete all pyc files from my project, it seems like these cached files were somehow causing this error.

Easiest way I found to do this was to navigate to my project folder in Windows explorer and searching for *.pyc, then selecting all (Ctrl+A) and deleting them (Ctrl+X).

Its possible I could have resolved my issues by just deleting the specific pyc file but I never tried this


回答 21

我遇到了同样的问题:Import error。此外,该库已正确安装了100%。问题的根源是在我的PC 3版本上安装了python(anaconda数据包)。这就是为什么没有将库安装到正确的位置的原因。之后,我只是在我的IDE PyCharm中更改为python的正确版本。

I faced the same problem: Import error. In addition the library’ve been installed 100% correctly. The source of the problem was that on my PC 3 version of python (anaconda packet) have been installed). This is why the library was installed no to the right place. After that I just changed to the proper version of python in the my IDE PyCharm.


回答 22

我有同样的错误。这是因为有人在与脚本相同的文件夹中创建了一个文件夹,该文件夹的名称与我从其他位置导入的模块冲突。它没有导入外部模块,而是查看了该文件夹内部,该文件夹显然不包含预期的模块。

I had the same error. It was caused by somebody creating a folder in the same folder as my script, the name of which conflicted with a module I was importing from elsewhere. Instead of importing the external module, it looked inside this folder which obviously didn’t contain the expected modules.


回答 23

我遇到了同样的问题(Python 2.7 Linux),我找到了解决方案,我想分享一下。就我而言,我的结构如下:

Booklet
-> __init__.py
-> Booklet.py
-> Question.py
default
-> __init_.py
-> main.py

在“ main.py”中,我尝试了以下所有组合,但均未成功:

from Booklet import Question
from Question import Question
from Booklet.Question import Question
from Booklet.Question import *
import Booklet.Question
# and many othet various combinations ...

解决方案比我想象的要简单得多。我将文件夹“ Booklet”重命名为“ booklet”,仅此而已。现在,Python可以通过在“ main.py”中使用以下代码来正常导入Question类:

from booklet.Booklet import Booklet
from booklet.Question import Question
from booklet.Question import AnotherClass

由此我可以得出结论,像“小册子”之类的包名称(文件夹)必须以小写开头,否则Python会将其与类名和文件名混淆。

显然,这不是您的问题,但是John Fouhy的回答非常好,并且该线程具有几乎所有可能导致此问题的东西。因此,这是一回事,我希望这可以对其他人有所帮助。

I had the same problem (Python 2.7 Linux), I have found the solution and i would like to share it. In my case i had the structure below:

Booklet
-> __init__.py
-> Booklet.py
-> Question.py
default
-> __init_.py
-> main.py

In ‘main.py’ I had tried unsuccessfully all the combinations bellow:

from Booklet import Question
from Question import Question
from Booklet.Question import Question
from Booklet.Question import *
import Booklet.Question
# and many othet various combinations ...

The solution was much more simple than I thought. I renamed the folder “Booklet” into “booklet” and that’s it. Now Python can import the class Question normally by using in ‘main.py’ the code:

from booklet.Booklet import Booklet
from booklet.Question import Question
from booklet.Question import AnotherClass

From this I can conclude that Package-Names (folders) like ‘booklet’ must start from lower-case, else Python confuses it with Class names and Filenames.

Apparently, this was not your problem, but John Fouhy’s answer is very good and this thread has almost anything that can cause this issue. So, this is one more thing and I hope that maybe this could help others.


回答 24

就我而言,我要包含package.egg文件夹的路径,而不是其下面的实际软件包。我将软件包复制到顶层,并且可以正常工作。

In my case I was including the path to package.egg folder rather than the actual package underneath. I copied the package to top level and it worked.


回答 25

这对我有用:__init__.py在父文件夹中创建文件(在您的情况下,在site-packages文件夹中)。并像这样导入:

from site-packages.toolkit.interface import interface

希望它对您也有用!

This worked for me: Created __init__.py file inside parent folder (in your case, inside site-packages folder). And imported like this:

from site-packages.toolkit.interface import interface

Hope it will be useful for you as well !


回答 26

在linux服务器上尝试 dos2unix script_name

pyc使用命令删除所有(如果有的话)文件find . -name '*.pyc' -delete

如果您在Windows上处理脚本,请重新运行

In linux server try dos2unix script_name

(remove all (if there is any) pyc files with command find . -name '*.pyc' -delete)

and re run in the case if you worked on script on windows


回答 27

就我而言,我是sys.path.insert()用来导入本地模块的,并且是module not found从另一个库中获取的。我不得不把sys.path.insert()进口的商品放在下面module not found。我想最好的做法是放在sys.path.insert()进口的底部。

In my case, I was using sys.path.insert() to import a local module and was getting module not found from a different library. I had to put sys.path.insert() below the imports that reported module not found. I guess the best practice is to put sys.path.insert() at the bottom of your imports.


使用“导入模块”还是“从模块导入”?

问题:使用“导入模块”还是“从模块导入”?

我试图找到一个综合指南,以决定是否最好使用import modulefrom module import?我刚开始使用Python,并且正在尝试着眼于最佳实践。

基本上,我希望有人能分享他们的经验,其他开发人员有什么喜好,以及避免遇到麻烦的最佳方法是什么?

I’ve tried to find a comprehensive guide on whether it is best to use import module or from module import? I’ve just started with Python and I’m trying to start off with best practices in mind.

Basically, I was hoping if anyone could share their experiences, what preferences other developers have and what’s the best way to avoid any gotchas down the road?


回答 0

import module和之间的区别from module import foo主要是主观的。选择最喜欢的一个,并在使用中保持一致。这里有一些要点可以帮助您做出决定。

import module

  • 优点:
    • 减少您的import报表维护。无需添加任何其他导入即可开始使用模块中的另一个项目
  • 缺点:
    • 输入module.foo代码可能既乏味又多余(可以通过使用import module as mo然后键入来最小化乏味mo.foo

from module import foo

  • 优点:
    • 减少打字使用 foo
    • 更好地控制可以访问模块的哪些项目
  • 缺点:
    • 要使用模块中的新项目,您必须更新import语句
    • 您会失去有关的信息foo。例如,ceil()math.ceil()

两种方法都可以接受,但不要使用from module import *

对于任何合理的大型代码集,如果您import *可能会将其固定在模块中,则无法删除。这是因为很难确定代码中使用的哪些项来自“模块”,这很容易达到您认为不再使用它们的地步,import但是很难确定。

The difference between import module and from module import foo is mainly subjective. Pick the one you like best and be consistent in your use of it. Here are some points to help you decide.

import module

  • Pros:
    • Less maintenance of your import statements. Don’t need to add any additional imports to start using another item from the module
  • Cons:
    • Typing module.foo in your code can be tedious and redundant (tedium can be minimized by using import module as mo then typing mo.foo)

from module import foo

  • Pros:
    • Less typing to use foo
    • More control over which items of a module can be accessed
  • Cons:
    • To use a new item from the module you have to update your import statement
    • You lose context about foo. For example, it’s less clear what ceil() does compared to math.ceil()

Either method is acceptable, but don’t use from module import *.

For any reasonable large set of code, if you import * you will likely be cementing it into the module, unable to be removed. This is because it is difficult to determine what items used in the code are coming from ‘module’, making it easy to get to the point where you think you don’t use the import any more but it’s extremely difficult to be sure.


回答 1

这里还有另一个细节,未提及,与写入模块有关。当然,这可能不是很常见,但是我不时需要它。

由于引用和名称绑定在Python中的工作方式,如果您想从该模块外部更新模块中的某些符号(例如foo.bar),并且要更改其他导入代码“ see”,则必须导入foo a某种方式。例如:

模块foo:

bar = "apples"

模块a:

import foo
foo.bar = "oranges"   # update bar inside foo module object

模块b:

import foo           
print foo.bar        # if executed after a's "foo.bar" assignment, will print "oranges"

但是,如果导入符号名称而不是模块名称,则将无法使用。

例如,如果我在模块a中这样做:

from foo import bar
bar = "oranges"

a之外的任何代码都不会将bar视为“橙色”,因为我对bar的设置仅影响模块a中的名称“ bar”,它没有“进入” foo模块对象并更新其“ bar”。

There’s another detail here, not mentioned, related to writing to a module. Granted this may not be very common, but I’ve needed it from time to time.

Due to the way references and name binding works in Python, if you want to update some symbol in a module, say foo.bar, from outside that module, and have other importing code “see” that change, you have to import foo a certain way. For example:

module foo:

bar = "apples"

module a:

import foo
foo.bar = "oranges"   # update bar inside foo module object

module b:

import foo           
print foo.bar        # if executed after a's "foo.bar" assignment, will print "oranges"

However, if you import symbol names instead of module names, this will not work.

For example, if I do this in module a:

from foo import bar
bar = "oranges"

No code outside of a will see bar as “oranges” because my setting of bar merely affected the name “bar” inside module a, it did not “reach into” the foo module object and update its “bar”.


回答 2

尽管已经有很多人对importvs进行了解释import from,但我还是想尝试多解释一些关于幕后发生的事情以及它发生的所有变化的位置。


import foo

导入foo,并在当前命名空间中创建对该模块的引用。然后,您需要定义完整的模块路径,以从模块内部访问特定的属性或方法。

例如foo.bar但不是bar

from foo import bar

导入foo,并创建对列出的所有成员(bar)的引用。不设置变量foo

例如bar但不是bazfoo.baz

from foo import *

导入foo并创建对该模块在当前命名空间中定义的所有公共对象的引用(__all__如果__all__存在,则列出的所有对象,否则所有不以开头的对象_)。不设置变量foo

例如barbaz但不是_quxfoo._qux


现在让我们看看我们何时进行操作import X.Y

>>> import sys
>>> import os.path

检查sys.modules名称osos.path

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

使用和检查globals()locals()命名空间字典:osos.path

 >>> globals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> locals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> globals()['os.path']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os.path'
>>>

从上面的示例中,我们发现仅os在本地和全局命名空间中插入了。因此,我们应该能够使用:

 >>> os
 <module 'os' from
  '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
 >>> os.path
 <module 'posixpath' from
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
 >>>

但是不是path

>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

os从locals()命名空间删除后,将无法访问它们osos.path即使它们存在于sys.modules中:

>>> del locals()['os']
>>> os
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

现在让我们谈谈import from

from

>>> import sys
>>> from os import path

sys.modulesos和检查os.path

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

我们发现,sys.modules通过使用与以前相同import name

OK,让我们检查一下它的外观locals()globals()命名空间字典:

>>> globals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> locals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['os']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os'
>>>

您可以使用名称访问,path而不能使用os.path

>>> path
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

让我们从中删除“路径” locals()

>>> del locals()['path']
>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

最后一个使用别名的示例:

>>> from os import path as HELL_BOY
>>> locals()['HELL_BOY']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['HELL_BOY']
<module 'posixpath' from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>

而且没有定义路径:

>>> globals()['path']
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 'path'
>>>

Even though many people already explained about import vs import from, I want to try to explain a bit more about what happens under the hood, and where all the places it changes are.


import foo:

Imports foo, and creates a reference to that module in the current namespace. Then you need to define completed module path to access a particular attribute or method from inside the module.

E.g. foo.bar but not bar

from foo import bar:

Imports foo, and creates references to all the members listed (bar). Does not set the variable foo.

E.g. bar but not baz or foo.baz

from foo import *:

Imports foo, and creates references to all public objects defined by that module in the current namespace (everything listed in __all__ if __all__ exists, otherwise everything that doesn’t start with _). Does not set the variable foo.

E.g. bar and baz but not _qux or foo._qux.


Now let’s see when we do import X.Y:

>>> import sys
>>> import os.path

Check sys.modules with name os and os.path:

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

Check globals() and locals() namespace dicts with os and os.path:

 >>> globals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> locals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> globals()['os.path']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os.path'
>>>

From the above example we found that only os is inserted in the local and global namespace. So, we should be able to use:

 >>> os
 <module 'os' from
  '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
 >>> os.path
 <module 'posixpath' from
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
 >>>

But not path.

>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

Once you delete the os from locals() namespace, you won’t be able to access os as well as os.path even though they exist in sys.modules:

>>> del locals()['os']
>>> os
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

Now let’s talk about import from:

from:

>>> import sys
>>> from os import path

Check sys.modules with os and os.path:

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

We found that in sys.modules we found as same as we did before by using import name

OK, let’s check how it looks like in locals() and globals() namespace dicts:

>>> globals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> locals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['os']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os'
>>>

You can access by using name path not by os.path:

>>> path
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

Let’s delete ‘path’ from locals():

>>> del locals()['path']
>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

One final example using an alias:

>>> from os import path as HELL_BOY
>>> locals()['HELL_BOY']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['HELL_BOY']
<module 'posixpath' from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>

And no path defined:

>>> globals()['path']
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 'path'
>>>

回答 3

两种方法都受支持是有原因的:有时候,一种方法比另一种更合适。

  • import module:当您使用模块中的许多位时很好。缺点是您需要使用模块名称来限定每个引用。

  • from module import ...:很高兴导入的项目无需模块名称前缀即可直接使用。缺点是您必须列出您使用的每件事,并且在代码中不清楚来源。

使用哪种方法取决于使代码清晰易读的方式,并且与个人喜好有关。我倾向于import module一般,因为在代码中很清楚对象或函数的来源。我在代码中大量from module import ...使用某些对象/函数时使用。

Both ways are supported for a reason: there are times when one is more appropriate than the other.

  • import module: nice when you are using many bits from the module. drawback is that you’ll need to qualify each reference with the module name.

  • from module import ...: nice that imported items are usable directly without module name prefix. The drawback is that you must list each thing you use, and that it’s not clear in code where something came from.

Which to use depends on which makes the code clear and readable, and has more than a little to do with personal preference. I lean toward import module generally because in the code it’s very clear where an object or function came from. I use from module import ... when I’m using some object/function a lot in the code.


回答 4

我个人总是使用

from package.subpackage.subsubpackage import module

然后以

module.function
module.modulevar

原因是同时有简短的调用,并且您清楚地定义了每个例程的模块命名空间,如果您必须在源代码中搜索给定模块的用法,这很有用。

不用说,不要使用import *,因为它会污染您的命名空间,并且不会告诉您给定函数的来源(来自哪个模块)

当然,如果两个不同软件包中的两个不同模块具有相同的模块名称,则可能会遇到麻烦。

from package1.subpackage import module
from package2.subpackage import module

在这种情况下,您当然会遇到麻烦,但是有一个强烈的暗示,即您的程序包布局存在缺陷,您必须重新考虑它。

I personally always use

from package.subpackage.subsubpackage import module

and then access everything as

module.function
module.modulevar

etc. The reason is that at the same time you have short invocation, and you clearly define the module namespace of each routine, something that is very useful if you have to search for usage of a given module in your source.

Needless to say, do not use the import *, because it pollutes your namespace and it does not tell you where a given function comes from (from which module)

Of course, you can run in trouble if you have the same module name for two different modules in two different packages, like

from package1.subpackage import module
from package2.subpackage import module

in this case, of course you run into troubles, but then there’s a strong hint that your package layout is flawed, and you have to rethink it.


回答 5

import module

当您将使用模块中的许多功能时,最好。

from module import function

当您只想避免使用模块中的所有函数和类型污染全局命名空间时,这是最好的选择function

import module

Is best when you will use many functions from the module.

from module import function

Is best when you want to avoid polluting the global namespace with all the functions and types from a module when you only need function.


回答 6

我刚刚发现了这两种方法之间的另一个细微差别。

如果模块foo使用以下导入:

from itertools import count

然后,模块bar可能会错误地使用count,就好像它是在中定义的foo,而不是在中定义的itertools

import foo
foo.count()

如果foo使用:

import itertools

该错误仍然可能,但不太可能发生。bar需要:

import foo
foo.itertools.count()

这给我带来了麻烦。我有一个模块,该模块错误地从未定义异常的模块导入了异常,而仅从其他模块(使用from module import SomeException)导入了异常。当不再需要导入并将其删除时,损坏的模块将被破坏。

I’ve just discovered one more subtle difference between these two methods.

If module foo uses a following import:

from itertools import count

Then module bar can by mistake use count as though it was defined in foo, not in itertools:

import foo
foo.count()

If foo uses:

import itertools

the mistake is still possible, but less likely to be made. bar needs to:

import foo
foo.itertools.count()

This caused some troubles to me. I had a module that by mistake imported an exception from a module that did not define it, only imported it from other module (using from module import SomeException). When the import was no longer needed and removed, the offending module was broken.


回答 7

这是另一个未提及的区别。这是从http://docs.python.org/2/tutorial/modules.html逐字复制的

请注意,使用时

from package import item

该项目可以是包的子模块(或子包),也可以是包中定义的其他名称,例如函数,类或变量。import语句首先测试项目是否在包装中定义;如果不是,则假定它是一个模块并尝试加载它。如果找不到它,则会引发ImportError异常。

相反,当使用类似

import item.subitem.subsubitem

除最后一个项目外,每个项目都必须是一个包装;最后一项可以是模块或包,但不能是上一项中定义的类或函数或变量。

Here is another difference not mentioned. This is copied verbatim from http://docs.python.org/2/tutorial/modules.html

Note that when using

from package import item

the item can be either a submodule (or subpackage) of the package, or some other name defined in the package, like a function, class or variable. The import statement first tests whether the item is defined in the package; if not, it assumes it is a module and attempts to load it. If it fails to find it, an ImportError exception is raised.

Contrarily, when using syntax like

import item.subitem.subsubitem

each item except for the last must be a package; the last item can be a module or a package but can’t be a class or function or variable defined in the previous item.


回答 8

由于我还是初学者,因此我将尝试以一种简单的方式来解释这一点:在Python中,我们有三种类型的import语句,它们是:

1.通用进口:

import math

这种类型的导入是我个人的最爱,这种导入技术的唯一缺点是,如果需要使用任何模块的功能,则必须使用以下语法:

math.sqrt(4)

当然,它会增加打字的工作量,但是作为一个初学者,它将帮助您跟踪与之相关的模块和功能(一个好的文本编辑器将大大减少打字的工作量,建议使用)。

使用以下import语句可以进一步减少打字工作:

import math as m

现在,math.sqrt()可以使用代替使用m.sqrt()

2.函数导入:

from math import sqrt

如果您的代码只需要访问模块中的单个或几个函数,而要使用模块中的任何新项,则必须更新import语句,则这种类型的导入最适合。

3.普遍进口:

from math import * 

尽管它可以显着减少键入工作,但是不建议这样做,因为它将用模块中的各种函数填充代码,并且它们的名称可能与用户定义函数的名称冲突。 例:

如果您有自己的名为sqrt的函数并且导入了数学运算,则该函数是安全的:存在您的sqrt和Math.sqrt。但是,如果从数学导入*进行操作,则会遇到问题:即,两个具有相同名称的不同函数。资料来源:Codecademy

Since I am also a beginner, I will be trying to explain this in a simple way: In Python, we have three types of import statements which are:

1. Generic imports:

import math

this type of import is my personal favorite, the only downside to this import technique is that if you need use any module’s function you must use the following syntax:

math.sqrt(4)

of course, it increases the typing effort but as a beginner, it will help you to keep track of module and function associated with it, (a good text editor will reduce the typing effort significantly and is recommended).

Typing effort can be further reduced by using this import statement:

import math as m

now, instead of using math.sqrt() you can use m.sqrt().

2. Function imports:

from math import sqrt

this type of import is best suited if your code only needs to access single or few functions from the module, but for using any new item from the module you have to update import statement.

3. Universal imports:

from math import * 

Although it reduces typing effort significantly but is not recommended because it will fill your code with various functions from the module and their name could conflict with the name of user-defined functions. example:

If you have a function of your very own named sqrt and you import math, your function is safe: there is your sqrt and there is math.sqrt. If you do from math import *, however, you have a problem: namely, two different functions with the exact same name. Source: Codecademy


回答 9

import package
import module

使用import,令牌必须是模块(包含Python命令的文件)或包(sys.path包含文件的文件夹__init__.py)。

有子包时:

import package1.package2.package
import package1.package2.module

为文件夹(封装)或文件(模块)的要求是相同的,但该文件夹或文件必须是内部package2必须是内部package1,并且两个package1package2必须包含__init__.py文件。https://docs.python.org/2/tutorial/modules.html

具有from导入样式:

from package1.package2 import package
from package1.package2 import module

程序包或模块将输入包含import语句的文件的命名空间用module(或package)代替package1.package2.module。您始终可以绑定到更方便的名称:

a = big_package_name.subpackage.even_longer_subpackage_name.function

只有from导入样式允许您命名特定的函数或变量:

from package3.module import some_function

被允许,但是

import package3.module.some_function 

不被允许。

import package
import module

With import, the token must be a module (a file containing Python commands) or a package (a folder in the sys.path containing a file __init__.py.)

When there are subpackages:

import package1.package2.package
import package1.package2.module

the requirements for folder (package) or file (module) are the same, but the folder or file must be inside package2 which must be inside package1, and both package1 and package2 must contain __init__.py files. https://docs.python.org/2/tutorial/modules.html

With the from style of import:

from package1.package2 import package
from package1.package2 import module

the package or module enters the namespace of the file containing the import statement as module (or package) instead of package1.package2.module. You can always bind to a more convenient name:

a = big_package_name.subpackage.even_longer_subpackage_name.function

Only the from style of import permits you to name a particular function or variable:

from package3.module import some_function

is allowed, but

import package3.module.some_function 

is not allowed.


回答 10

补充说一下from x import *:除了使人更难分辨名称的来源之外,还抛出了像Pylint这样的代码检查器。他们会将这些名称报告为未定义的变量。

To add to what people have said about from x import *: besides making it more difficult to tell where names came from, this throws off code checkers like Pylint. They will report those names as undefined variables.


回答 11

我自己的答案主要取决于首先要使用的模块数量。如果我只使用一两个,那么我将经常使用from…,import因为它使文件其余部分的击键次数减少,但是如果我要使用许多不同的模块,我更喜欢import因为这意味着每个模块引用都是自记录的。我可以看到每个符号的来源,而不必四处寻找。

通常,我更喜欢纯文本导入的自我记录样式,仅当要输入的模块名称次数超过10到20时才更改为from .. import,即使只有一个模块被导入。

My own answer to this depends mostly on first, how many different modules I’ll be using. If i’m only going to use one or two, I’ll often use fromimport since it makes for fewer keystrokes in the rest of the file, but if I’m going to make use of many different modules, I prefer just import because that means that each module reference is self-documenting. I can see where each symbol comes from without having to hunt around.

Usuaully I prefer the self documenting style of plain import and only change to from.. import when the number of times I have to type the module name grows above 10 to 20, even if there’s only one module being imported.


回答 12

其中一个显著差异,我发现它的出奇,没有人一直在谈论的是使用纯进口,您可以访问private variableprivate functions从导入模块,这是不可能的从导入语句。

在此处输入图片说明

图片中的代码:

setting.py

public_variable = 42
_private_variable = 141
def public_function():
    print("I'm a public function! yay!")
def _private_function():
    print("Ain't nobody accessing me from another module...usually")

plain_importer.py

import settings
print (settings._private_variable)
print (settings.public_variable)
settings.public_function()
settings._private_function()

# Prints:
# 141
# 42
# I'm a public function! yay!
# Ain't nobody accessing me from another module...usually

from_importer.py

from settings import *
#print (_private_variable) #doesn't work
print (public_variable)
public_function()
#_private_function()   #doesn't work

One of the significant difference I found out which surprisingly no-one has talked about is that using plain import you can access private variable and private functions from the imported module, which isn’t possible with from-import statement.

enter image description here

Code in image:

setting.py

public_variable = 42
_private_variable = 141
def public_function():
    print("I'm a public function! yay!")
def _private_function():
    print("Ain't nobody accessing me from another module...usually")

plain_importer.py

import settings
print (settings._private_variable)
print (settings.public_variable)
settings.public_function()
settings._private_function()

# Prints:
# 141
# 42
# I'm a public function! yay!
# Ain't nobody accessing me from another module...usually

from_importer.py

from settings import *
#print (_private_variable) #doesn't work
print (public_variable)
public_function()
#_private_function()   #doesn't work

回答 13

导入模块-您无需付出额外的努力即可从模块中获取其他东西。它具有诸如冗余键入之类的缺点

从模块导入-减少键入操作,更多地控制可以访问模块的项目。要使用模块中的新项目,必须更新导入语句。

Import Module – You don’t need additional efforts to fetch another thing from module. It has disadvantages such as redundant typing

Module Import From – Less typing &More control over which items of a module can be accessed.To use a new item from the module you have to update your import statement.


回答 14

有一些内置模块主要包含裸函数(base64mathosshutilsystime等),将这些裸函数绑定到某些命名空间绝对是一个好习惯,从而提高了您的可读性码。考虑没有这些命名空间的情况下,理解这些功能的含义会更加困难:

copysign(foo, bar)
monotonic()
copystat(foo, bar)

而不是将它们绑定到某个模块时:

math.copysign(foo, bar)
time.monotonic()
shutil.copystat(foo, bar)

有时甚至需要命名空间来避免不同模块之间的冲突(json.loadpickle.load


另一方面,有些模块主要包含类(configparserdatetimetempfilezipfile,…),其中许多模块使类名变得不言而喻:

configparser.RawConfigParser()
datetime.DateTime()
email.message.EmailMessage()
tempfile.NamedTemporaryFile()
zipfile.ZipFile()

因此,在将这些类与代码中的其他模块命名空间一起使用时是否存在争议,是否会增加一些新信息还是仅仅是延长代码长度,就存在争议。

There are some builtin modules that contain mostly bare functions (base64, math, os, shutil, sys, time, …) and it is definitely a good practice to have these bare functions bound to some namespace and thus improve the readability of your code. Consider how more difficult is to understand the meaning of these functions without their namespace:

copysign(foo, bar)
monotonic()
copystat(foo, bar)

than when they are bound to some module:

math.copysign(foo, bar)
time.monotonic()
shutil.copystat(foo, bar)

Sometimes you even need the namespace to avoid conflicts between different modules (json.load vs. pickle.load)


On the other hand there are some modules that contain mostly classes (configparser, datetime, tempfile, zipfile, …) and many of them make their class names self-explanatory enough:
configparser.RawConfigParser()
datetime.DateTime()
email.message.EmailMessage()
tempfile.NamedTemporaryFile()
zipfile.ZipFile()

so there can be a debate whether using these classes with the additional module namespace in your code adds some new information or just lengthens the code.


回答 15

我想补充一点,在导入调用期间需要考虑一些事项:

我有以下结构:

mod/
    __init__.py
    main.py
    a.py
    b.py
    c.py
    d.py

main.py:

import mod.a
import mod.b as b
from mod import c
import d

dis.dis显示了不同之处:

  1           0 LOAD_CONST               0 (-1)
              3 LOAD_CONST               1 (None)
              6 IMPORT_NAME              0 (mod.a)
              9 STORE_NAME               1 (mod)

  2          12 LOAD_CONST               0 (-1)
             15 LOAD_CONST               1 (None)
             18 IMPORT_NAME              2 (b)
             21 STORE_NAME               2 (b)

  3          24 LOAD_CONST               0 (-1)
             27 LOAD_CONST               2 (('c',))
             30 IMPORT_NAME              1 (mod)
             33 IMPORT_FROM              3 (c)
             36 STORE_NAME               3 (c)
             39 POP_TOP

  4          40 LOAD_CONST               0 (-1)
             43 LOAD_CONST               1 (None)
             46 IMPORT_NAME              4 (mod.d)
             49 LOAD_ATTR                5 (d)
             52 STORE_NAME               5 (d)
             55 LOAD_CONST               1 (None)

最后,它们看起来相同(每个示例中的结果都是STORE_NAME),但是值得注意的是,如果您需要考虑以下四个循环导入:

例子1

foo/
   __init__.py
   a.py
   b.py
a.py:
import foo.b 
b.py:
import foo.a
>>> import foo.a
>>>

这有效

例子2

bar/
   __init__.py
   a.py
   b.py
a.py:
import bar.b as b
b.py:
import bar.a as a
>>> import bar.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "bar\a.py", line 1, in <module>
    import bar.b as b
  File "bar\b.py", line 1, in <module>
    import bar.a as a
AttributeError: 'module' object has no attribute 'a'

没有骰子

例子3

baz/
   __init__.py
   a.py
   b.py
a.py:
from baz import b
b.py:
from baz import a
>>> import baz.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "baz\a.py", line 1, in <module>
    from baz import b
  File "baz\b.py", line 1, in <module>
    from baz import a
ImportError: cannot import name a

类似的问题…但是从x import y明显不同于与import import xy和y相同

例子4

qux/
   __init__.py
   a.py
   b.py
a.py:
import b 
b.py:
import a
>>> import qux.a
>>>

这个也可以

I would like to add to this, there are somethings to consider during the import calls:

I have the following structure:

mod/
    __init__.py
    main.py
    a.py
    b.py
    c.py
    d.py

main.py:

import mod.a
import mod.b as b
from mod import c
import d

dis.dis shows the difference:

  1           0 LOAD_CONST               0 (-1)
              3 LOAD_CONST               1 (None)
              6 IMPORT_NAME              0 (mod.a)
              9 STORE_NAME               1 (mod)

  2          12 LOAD_CONST               0 (-1)
             15 LOAD_CONST               1 (None)
             18 IMPORT_NAME              2 (b)
             21 STORE_NAME               2 (b)

  3          24 LOAD_CONST               0 (-1)
             27 LOAD_CONST               2 (('c',))
             30 IMPORT_NAME              1 (mod)
             33 IMPORT_FROM              3 (c)
             36 STORE_NAME               3 (c)
             39 POP_TOP

  4          40 LOAD_CONST               0 (-1)
             43 LOAD_CONST               1 (None)
             46 IMPORT_NAME              4 (mod.d)
             49 LOAD_ATTR                5 (d)
             52 STORE_NAME               5 (d)
             55 LOAD_CONST               1 (None)

In the end they look the same (STORE_NAME is result in each example), but this is worth noting if you need to consider the following four circular imports:

example1

foo/
   __init__.py
   a.py
   b.py
a.py:
import foo.b 
b.py:
import foo.a
>>> import foo.a
>>>

This works

example2

bar/
   __init__.py
   a.py
   b.py
a.py:
import bar.b as b
b.py:
import bar.a as a
>>> import bar.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "bar\a.py", line 1, in <module>
    import bar.b as b
  File "bar\b.py", line 1, in <module>
    import bar.a as a
AttributeError: 'module' object has no attribute 'a'

No dice

example3

baz/
   __init__.py
   a.py
   b.py
a.py:
from baz import b
b.py:
from baz import a
>>> import baz.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "baz\a.py", line 1, in <module>
    from baz import b
  File "baz\b.py", line 1, in <module>
    from baz import a
ImportError: cannot import name a

Similar issue… but clearly from x import y is not the same as import import x.y as y

example4

qux/
   __init__.py
   a.py
   b.py
a.py:
import b 
b.py:
import a
>>> import qux.a
>>>

This one also works


回答 16

这是我当前目录的目录结构:

.  
└─a  
   └─b  
     └─c
  1. import语句会记住所有中间名称
    这些名称必须是合格的:

    In[1]: import a.b.c
    
    In[2]: a
    Out[2]: <module 'a' (namespace)>
    
    In[3]: a.b
    Out[3]: <module 'a.b' (namespace)>
    
    In[4]: a.b.c
    Out[4]: <module 'a.b.c' (namespace)>
  2. from ... import ...语句记住导入的名称
    此名称不能为限定名称:

    In[1]: from a.b import c
    
    In[2]: a
    NameError: name 'a' is not defined
    
    In[2]: a.b
    NameError: name 'a' is not defined
    
    In[3]: a.b.c
    NameError: name 'a' is not defined
    
    In[4]: c
    Out[4]: <module 'a.b.c' (namespace)>

  • 注意:当然,我在步骤1和2之间重新启动了Python控制台。

This is my directory structure of my current directory:

.  
└─a  
   └─b  
     └─c
  1. The import statement remembers all intermediate names.
    These names have to be qualified:

    In[1]: import a.b.c
    
    In[2]: a
    Out[2]: <module 'a' (namespace)>
    
    In[3]: a.b
    Out[3]: <module 'a.b' (namespace)>
    
    In[4]: a.b.c
    Out[4]: <module 'a.b.c' (namespace)>
    
  2. The from ... import ... statement remembers only the imported name.
    This name must not be qualified:

    In[1]: from a.b import c
    
    In[2]: a
    NameError: name 'a' is not defined
    
    In[2]: a.b
    NameError: name 'a' is not defined
    
    In[3]: a.b.c
    NameError: name 'a' is not defined
    
    In[4]: c
    Out[4]: <module 'a.b.c' (namespace)>
    

  • Note: Of course, I restarted my Python console between steps 1 and 2.

回答 17

正如Jan Wrobel所提到的,不同进口的一个方面是进口的公开方式。

模块神话

from math import gcd
...

使用神话

import mymath
mymath.gcd(30, 42)  # will work though maybe not expected

如果我gcd仅为内部使用而导入,而不是向的用户公开mymath,可能会带来不便。我经常遇到这种情况,在大多数情况下,我想“保持模块清洁”。

除了扬·沃伯Jan Wrobel)提议通过使用import math来进一步掩盖这一点之外,我还开始使用领先的下划线来掩盖进口的隐瞒:

# for instance...
from math import gcd as _gcd
# or...
import math as _math

在较大的项目中,这种“最佳实践”使我能够精确控制后续进口中公开的内容和未公开内容。这样可以使我的模块保持清洁,并以一定规模的项目回报。

As Jan Wrobel mentions, one aspect of the different imports is in which way the imports are disclosed.

Module mymath

from math import gcd
...

Use of mymath:

import mymath
mymath.gcd(30, 42)  # will work though maybe not expected

If I imported gcd only for internal use, not to disclose it to users of mymath, this can be inconvenient. I have this pretty often, and in most cases I want to “keep my modules clean”.

Apart from the proposal of Jan Wrobel to obscure this a bit more by using import math instead, I have started to hide imports from disclosure by using a leading underscore:

# for instance...
from math import gcd as _gcd
# or...
import math as _math

In larger projects this “best practice” allows my to exactly control what is disclosed to subsequent imports and what isn’t. This keeps my modules clean and pays back at a certain size of project.


如何卸载(重新加载)模块?

问题:如何卸载(重新加载)模块?

我有一台运行时间较长的Python服务器,并且希望能够在不重新启动服务器的情况下升级服务。最好的方法是什么?

if foo.py has changed:
    unimport foo  <-- How do I do this?
    import foo
    myfoo = foo.Foo()

I have a long-running Python server and would like to be able to upgrade a service without restarting the server. What’s the best way do do this?

if foo.py has changed:
    unimport foo  <-- How do I do this?
    import foo
    myfoo = foo.Foo()

回答 0

您可以使用reload内置函数(仅适用于Python 3.4+)重新导入已导入的模块:

from importlib import reload  
import foo

while True:
    # Do some things.
    if is_changed(foo):
        foo = reload(foo)

在Python 3中,reload已移至imp模块。在3.4中,imp不推荐使用importlib,而reload在中添加了。当定位到3或更高版本时,在调用reload或导入它时参考相应的模块。

我认为这就是您想要的。诸如Django开发服务器之类的Web服务器都使用此服务器,这样您就可以查看代码更改的效果,而无需重新启动服务器进程本身。

引用文档:

重新编译Python模块的代码并重新执行模块级代码,从而定义了一组新对象,这些对象绑定到模块字典中的名称。扩展模块的init函数不会被第二次调用。与Python中的所有其他对象一样,旧对象仅在其引用计数降至零后才被回收。模块命名空间中的名称将更新为指向任何新的或更改的对象。对旧对象的其他引用(例如模块外部的名称)不会反弹以引用新对象,并且如果需要的话,必须在出现它们的每个命名空间中进行更新。

正如您在问题中指出的那样,Foo如果Foo类驻留在foo模块中,则必须重构对象。

You can reload a module when it has already been imported by using the reload builtin function (Python 3.4+ only):

from importlib import reload  
import foo

while True:
    # Do some things.
    if is_changed(foo):
        foo = reload(foo)

In Python 3, reload was moved to the imp module. In 3.4, imp was deprecated in favor of importlib, and reload was added to the latter. When targeting 3 or later, either reference the appropriate module when calling reload or import it.

I think that this is what you want. Web servers like Django’s development server use this so that you can see the effects of your code changes without restarting the server process itself.

To quote from the docs:

Python modules’ code is recompiled and the module-level code reexecuted, defining a new set of objects which are bound to names in the module’s dictionary. The init function of extension modules is not called a second time. As with all other objects in Python the old objects are only reclaimed after their reference counts drop to zero. The names in the module namespace are updated to point to any new or changed objects. Other references to the old objects (such as names external to the module) are not rebound to refer to the new objects and must be updated in each namespace where they occur if that is desired.

As you noted in your question, you’ll have to reconstruct Foo objects if the Foo class resides in the foo module.


回答 1

在Python 3.0–3.3中,您将使用: imp.reload(module)

BDFL已经回答了这个问题。

但是,imp在3.4中已弃用,importlib改为(感谢@Stefan!)。

因此,importlib.reload(module)尽管我不确定,但您现在应该使用。

In Python 3.0–3.3 you would use: imp.reload(module)

The BDFL has answered this question.

However, imp was deprecated in 3.4, in favour of importlib (thanks @Stefan!).

I think, therefore, you’d now use importlib.reload(module), although I’m not sure.


回答 2

如果模块不是纯Python,则删除模块可能会特别困难。

以下是一些信息:我如何真正删除导入的模块?

您可以使用sys.getrefcount()来查找实际的引用数。

>>> import sys, empty, os
>>> sys.getrefcount(sys)
9
>>> sys.getrefcount(os)
6
>>> sys.getrefcount(empty)
3

大于3的数字表示很难摆脱该模块。本地的“空”(不包含任何内容)模块应在之后收集垃圾

>>> del sys.modules["empty"]
>>> del empty

作为第三个引用是getrefcount()函数的构件。

It can be especially difficult to delete a module if it is not pure Python.

Here is some information from: How do I really delete an imported module?

You can use sys.getrefcount() to find out the actual number of references.

>>> import sys, empty, os
>>> sys.getrefcount(sys)
9
>>> sys.getrefcount(os)
6
>>> sys.getrefcount(empty)
3

Numbers greater than 3 indicate that it will be hard to get rid of the module. The homegrown “empty” (containing nothing) module should be garbage collected after

>>> del sys.modules["empty"]
>>> del empty

as the third reference is an artifact of the getrefcount() function.


回答 3

reload(module),但前提是它是完全独立的。如果还有其他引用该模块(或属于该模块的任何对象)的引用,则您将得到细微而奇怪的错误,这些错误是由于旧代码的停留时间超出您的预期而导致的,并且isinstance无法在不同版本的相同的代码。

如果您具有单向依赖关系,则还必须重新加载所有依赖于重新加载的模块的模块,以摆脱对旧代码的所有引用。然后递归依赖于重新加载的模块重新加载模块。

如果您有循环依赖关系(例如在处理重新加载程序包时非常常见),则必须一次性卸载组中的所有模块。您无法执行此操作,reload()因为它将在刷新依赖关系之前重新导入每个模块,从而允许旧引用爬入新模块。

在这种情况下,唯一的方法是hack sys.modules,这是不受支持的。您必须仔细检查并删除sys.modules要在下次导入时重新加载的每个条目,还必须删除其值None用于处理实现问题的条目,以缓存失败的相对导入。它不是很好,但是只要您有一套完全独立的依赖项,并且不会将引用保留在其代码库之外,那么它就是可行的。

最好重新启动服务器。:-)

reload(module), but only if it’s completely stand-alone. If anything else has a reference to the module (or any object belonging to the module), then you’ll get subtle and curious errors caused by the old code hanging around longer than you expected, and things like isinstance not working across different versions of the same code.

If you have one-way dependencies, you must also reload all modules that depend on the the reloaded module to get rid of all the references to the old code. And then reload modules that depend on the reloaded modules, recursively.

If you have circular dependencies, which is very common for example when you are dealing with reloading a package, you must unload all the modules in the group in one go. You can’t do this with reload() because it will re-import each module before its dependencies have been refreshed, allowing old references to creep into new modules.

The only way to do it in this case is to hack sys.modules, which is kind of unsupported. You’d have to go through and delete each sys.modules entry you wanted to be reloaded on next import, and also delete entries whose values are None to deal with an implementation issue to do with caching failed relative imports. It’s not terribly nice but as long as you have a fully self-contained set of dependencies that doesn’t leave references outside its codebase, it’s workable.

It’s probably best to restart the server. :-)


回答 4

if 'myModule' in sys.modules:  
    del sys.modules["myModule"]
if 'myModule' in sys.modules:  
    del sys.modules["myModule"]

回答 5

对于Python 2,请使用内置函数reload()

reload(module)

对于Python 2和3.2–3.3,请使用从模块imp重新加载

import imp
imp.reload(module)

但是从3.4版开始imp 不推荐使用importlib,所以请使用:

import importlib
importlib.reload(module)

要么

from importlib import reload
reload(module)

For Python 2 use built-in function reload():

reload(module)

For Python 2 and 3.2–3.3 use reload from module imp:

import imp
imp.reload(module)

But imp is deprecated since version 3.4 in favor of importlib, so use:

import importlib
importlib.reload(module)

or

from importlib import reload
reload(module)

回答 6

以下代码允许您与Python 2/3兼容:

try:
    reload
except NameError:
    # Python 3
    from imp import reload

您可以reload()在两个版本中都使用它,这使事情变得更简单。

The following code allows you Python 2/3 compatibility:

try:
    reload
except NameError:
    # Python 3
    from imp import reload

The you can use it as reload() in both versions which makes things simpler.


回答 7

接受的答案不处理from X import Y的情况。这段代码可以处理它以及标准的导入情况:

def importOrReload(module_name, *names):
    import sys

    if module_name in sys.modules:
        reload(sys.modules[module_name])
    else:
        __import__(module_name, fromlist=names)

    for name in names:
        globals()[name] = getattr(sys.modules[module_name], name)

# use instead of: from dfly_parser import parseMessages
importOrReload("dfly_parser", "parseMessages")

在重载的情况下,我们将顶级名称重新分配给新重载的模块中存储的值,从而更新它们。

The accepted answer doesn’t handle the from X import Y case. This code handles it and the standard import case as well:

def importOrReload(module_name, *names):
    import sys

    if module_name in sys.modules:
        reload(sys.modules[module_name])
    else:
        __import__(module_name, fromlist=names)

    for name in names:
        globals()[name] = getattr(sys.modules[module_name], name)

# use instead of: from dfly_parser import parseMessages
importOrReload("dfly_parser", "parseMessages")

In the reloading case, we reassign the top level names to the values stored in the newly reloaded module, which updates them.


回答 8

这是重新加载模块的现代方法:

from importlib import reload

如果要支持3.5之前的Python版本,请尝试以下操作:

from sys import version_info
if version_info[0] < 3:
    pass # Python 2 has built in reload
elif version_info[0] == 3 and version_info[1] <= 4:
    from imp import reload # Python 3.0 - 3.4 
else:
    from importlib import reload # Python 3.5+

要使用它,请运行reload(MODULE),并替换MODULE为要重新加载的模块。

例如,reload(math)将重新加载math模块。

This is the modern way of reloading a module:

from importlib import reload

If you want to support versions of Python older than 3.5, try this:

from sys import version_info
if version_info[0] < 3:
    pass # Python 2 has built in reload
elif version_info[0] == 3 and version_info[1] <= 4:
    from imp import reload # Python 3.0 - 3.4 
else:
    from importlib import reload # Python 3.5+

To use it, run reload(MODULE), replacing MODULE with the module you want to reload.

For example, reload(math) will reload the math module.


回答 9

如果您不在服务器中,但是正在开发并且需要经常重新加载模块,那么这里是个不错的提示。

首先,请确保您使用的是Jupyter Notebook项目中出色的IPython shell。安装Jupyter后,你可以启动它ipython,或者jupyter console,甚至更好,jupyter qtconsole,这将为您提供一个漂亮的彩色控制台,并在任何OS中均具有代码完成功能。

现在在您的外壳中,键入:

%load_ext autoreload
%autoreload 2

现在,每次您运行脚本时,模块都会重新加载。

除了2,自动重载魔术还有其他选择

%autoreload
Reload all modules (except those excluded by %aimport) automatically now.

%autoreload 0
Disable automatic reloading.

%autoreload 1
Reload all modules imported with %aimport every time before executing the Python code typed.

%autoreload 2
Reload all modules (except those excluded by %aimport) every time before
executing the Python code typed.

If you are not in a server, but developing and need to frequently reload a module, here’s a nice tip.

First, make sure you are using the excellent IPython shell, from the Jupyter Notebook project. After installing Jupyter, you can start it with ipython, or jupyter console, or even better, jupyter qtconsole, which will give you a nice colorized console with code completion in any OS.

Now in your shell, type:

%load_ext autoreload
%autoreload 2

Now, every time you run your script, your modules will be reloaded.

Beyond the 2, there are other options of the autoreload magic:

%autoreload
Reload all modules (except those excluded by %aimport) automatically now.

%autoreload 0
Disable automatic reloading.

%autoreload 1
Reload all modules imported with %aimport every time before executing the Python code typed.

%autoreload 2
Reload all modules (except those excluded by %aimport) every time before
executing the Python code typed.

回答 10

对于那些想要卸载所有模块的人(在Emacs下的Python解释器中运行时):

   for mod in sys.modules.values():
      reload(mod)

有关更多信息,请参见重新加载Python模块

For those like me who want to unload all modules (when running in the Python interpreter under Emacs):

   for mod in sys.modules.values():
      reload(mod)

More information is in Reloading Python modules.


回答 11

追求特质有一个可以很好地完成此任务的模块。https://traits.readthedocs.org/zh/4.3.0/_modules/traits/util/refresh.html

它将重新加载已更改的所有模块,并更新正在使用该模块的其他模块和实例对象。大多数情况下它不起作用__very_private__方法使用,并且可能会阻塞类继承,但是它为我节省了编写PyQt guis或在Maya或Nuke等程序中运行的东西时不必重新启动主机应用程序的疯狂时间。它可能在20%到30%的时间内无效,但是仍然非常有用。

Enthought的软件包不会在文件更改时立即重新加载文件-您必须明确地调用它-但是如果您真的需要它,那么实现起来应该不那么困难

Enthought Traits has a module that works fairly well for this. https://traits.readthedocs.org/en/4.3.0/_modules/traits/util/refresh.html

It will reload any module that has been changed, and update other modules and instanced objects that are using it. It does not work most of the time with __very_private__ methods, and can choke on class inheritance, but it saves me crazy amounts of time from having to restart the host application when writing PyQt guis, or stuff that runs inside programs such as Maya or Nuke. It doesn’t work maybe 20-30 % of the time, but it’s still incredibly helpful.

Enthought’s package doesn’t reload files the moment they change – you have to call it explicitely – but that shouldn’t be all that hard to implement if you really need it


回答 12

那些正在使用python 3并从importlib重新加载的人。

如果您遇到问题,例如似乎模块无法重新加载…那是因为它需要一些时间来重新编译pyc(最多60秒)。我写此提示只是想知道您是否遇到过此类问题。

Those who are using python 3 and reload from importlib.

If you have problems like it seems that module doesn’t reload… That is because it needs some time to recompile pyc (up to 60 sec).I writing this hint just that you know if you have experienced this kind of problem.


回答 13

2018-02-01

  1. foo必须提前成功导入模块。
  2. from importlib import reloadreload(foo)

31.5。importlib —导入的实现— Python 3.6.4文档

2018-02-01

  1. module foo must be imported successfully in advance.
  2. from importlib import reload, reload(foo)

31.5. importlib — The implementation of import — Python 3.6.4 documentation


回答 14

其他选择。看到Python默认值importlib.reload将只是重新导入作为参数传递的库。它不会重新加载您的lib导入的库。如果您更改了很多文件并且要导入的包有些复杂,则必须进行一次深度重载

如果您安装了IPythonJupyter,则可以使用一个函数来深度重新加载所有库:

from IPython.lib.deepreload import reload as dreload
dreload(foo)

如果您没有Jupyter,请在外壳程序中使用以下命令将其安装:

pip3 install jupyter

Other option. See that Python default importlib.reload will just reimport the library passed as an argument. It won’t reload the libraries that your lib import. If you changed a lot of files and have a somewhat complex package to import, you must do a deep reload.

If you have IPython or Jupyter installed, you can use a function to deep reload all libs:

from IPython.lib.deepreload import reload as dreload
dreload(foo)

If you don’t have Jupyter, install it with this command in your shell:

pip3 install jupyter

回答 15

编辑(答案V2)

之前的解决方案仅适用于获取重置信息,但是它不会更改所有引用(超出reload但少于要求)。为了实际设置所有引用,我必须进入垃圾收集器,并在那里重写引用。现在它就像一种魅力!

请注意,这不会如果GC已关闭,或者重新加载了不受GC监视的数据,则。如果您不想弄乱GC,那么原始答案可能就足够了。

新代码:

import importlib
import inspect
import gc
from weakref import ref


def reset_module(module, inner_modules_also=True):
    """
    This function is a stronger form of importlib's `reload` function. What it does, is that aside from reloading a
    module, it goes to the old instance of the module, and sets all the (not read-only) attributes, functions and classes
    to be the reloaded-module's
    :param module: The module to reload (module reference, not the name)
    :param inner_modules_also: Whether to treat ths module as a package as well, and reload all the modules within it.
    """

    # For the case when the module is actually a package
    if inner_modules_also:
        submods = {submod for _, submod in inspect.getmembers(module)
                   if (type(submod).__name__ == 'module') and (submod.__package__.startswith(module.__name__))}
        for submod in submods:
            reset_module(submod, True)

    # First, log all the references before reloading (because some references may be changed by the reload operation).
    module_tree = _get_tree_references_to_reset_recursively(module, module.__name__)

    new_module = importlib.reload(module)
    _reset_item_recursively(module, module_tree, new_module)


def _update_referrers(item, new_item):
    refs = gc.get_referrers(item)

    weak_ref_item = ref(item)
    for coll in refs:
        if type(coll) == dict:
            enumerator = coll.keys()
        elif type(coll) == list:
            enumerator = range(len(coll))
        else:
            continue

        for key in enumerator:

            if weak_ref_item() is None:
                # No refs are left in the GC
                return

            if coll[key] is weak_ref_item():
                coll[key] = new_item

def _get_tree_references_to_reset_recursively(item, module_name, grayed_out_item_ids = None):
    if grayed_out_item_ids is None:
        grayed_out_item_ids = set()

    item_tree = dict()
    attr_names = set(dir(item)) - _readonly_attrs
    for sub_item_name in attr_names:

        sub_item = getattr(item, sub_item_name)
        item_tree[sub_item_name] = [sub_item, None]

        try:
            # Will work for classes and functions defined in that module.
            mod_name = sub_item.__module__
        except AttributeError:
            mod_name = None

        # If this item was defined within this module, deep-reset
        if (mod_name is None) or (mod_name != module_name) or (id(sub_item) in grayed_out_item_ids) \
                or isinstance(sub_item, EnumMeta):
            continue

        grayed_out_item_ids.add(id(sub_item))
        item_tree[sub_item_name][1] = \
            _get_tree_references_to_reset_recursively(sub_item, module_name, grayed_out_item_ids)

    return item_tree


def _reset_item_recursively(item, item_subtree, new_item):

    # Set children first so we don't lose the current references.
    if item_subtree is not None:
        for sub_item_name, (sub_item, sub_item_tree) in item_subtree.items():

            try:
                new_sub_item = getattr(new_item, sub_item_name)
            except AttributeError:
                # The item doesn't exist in the reloaded module. Ignore.
                continue

            try:
                # Set the item
                _reset_item_recursively(sub_item, sub_item_tree, new_sub_item)
            except Exception as ex:
                pass

    _update_referrers(item, new_item)

原始答案

就像@bobince的答案中所写,如果另一个模块中已经存在对该模块的引用(特别是如果它是使用as诸如import numpy as np),则该实例将不会被覆盖。

在应用要求配置模块处于“干净状态”状态的测试时,这对我来说是相当麻烦的,因此我编写了一个名为的函数,该函数reset_module使用importlibreload函数并递归覆盖所有声明的模块的属性。已通过Python 3.6版进行了测试。

import importlib
import inspect
from enum import EnumMeta

_readonly_attrs = {'__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__',
               '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__func__', '__ge__', '__get__',
               '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__',
               '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__',
               '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__',
               '__subclasshook__', '__weakref__', '__members__', '__mro__', '__itemsize__', '__isabstractmethod__',
               '__basicsize__', '__base__'}


def reset_module(module, inner_modules_also=True):
    """
    This function is a stronger form of importlib's `reload` function. What it does, is that aside from reloading a
    module, it goes to the old instance of the module, and sets all the (not read-only) attributes, functions and classes
    to be the reloaded-module's
    :param module: The module to reload (module reference, not the name)
    :param inner_modules_also: Whether to treat ths module as a package as well, and reload all the modules within it.
    """

    new_module = importlib.reload(module)

    reset_items = set()

    # For the case when the module is actually a package
    if inner_modules_also:
        submods = {submod for _, submod in inspect.getmembers(module)
                   if (type(submod).__name__ == 'module') and (submod.__package__.startswith(module.__name__))}
        for submod in submods:
            reset_module(submod, True)

    _reset_item_recursively(module, new_module, module.__name__, reset_items)


def _reset_item_recursively(item, new_item, module_name, reset_items=None):
    if reset_items is None:
        reset_items = set()

    attr_names = set(dir(item)) - _readonly_attrs

    for sitem_name in attr_names:

        sitem = getattr(item, sitem_name)
        new_sitem = getattr(new_item, sitem_name)

        try:
            # Set the item
            setattr(item, sitem_name, new_sitem)

            try:
                # Will work for classes and functions defined in that module.
                mod_name = sitem.__module__
            except AttributeError:
                mod_name = None

            # If this item was defined within this module, deep-reset
            if (mod_name is None) or (mod_name != module_name) or (id(sitem) in reset_items) \
                    or isinstance(sitem, EnumMeta):  # Deal with enums
                continue

            reset_items.add(id(sitem))
            _reset_item_recursively(sitem, new_sitem, module_name, reset_items)
        except Exception as ex:
            raise Exception(sitem_name) from ex

注意:小心使用!在非外围模块(例如,定义外部使用的类的模块)上使用它们可能会导致Python内部发生问题(例如,酸洗/不酸洗问题)。

Edit (Answer V2)

The solution from before is good for just getting the reset information, but it will not change all the references (more than reload but less then required). To actually set all the references as well, I had to go into the garbage collector, and rewrite the references there. Now it works like a charm!

Note that this will not work if the GC is turned off, or if reloading data that’s not monitored by the GC. If you don’t want to mess with the GC, the original answer might be enough for you.

New code:

import importlib
import inspect
import gc
from weakref import ref


def reset_module(module, inner_modules_also=True):
    """
    This function is a stronger form of importlib's `reload` function. What it does, is that aside from reloading a
    module, it goes to the old instance of the module, and sets all the (not read-only) attributes, functions and classes
    to be the reloaded-module's
    :param module: The module to reload (module reference, not the name)
    :param inner_modules_also: Whether to treat ths module as a package as well, and reload all the modules within it.
    """

    # For the case when the module is actually a package
    if inner_modules_also:
        submods = {submod for _, submod in inspect.getmembers(module)
                   if (type(submod).__name__ == 'module') and (submod.__package__.startswith(module.__name__))}
        for submod in submods:
            reset_module(submod, True)

    # First, log all the references before reloading (because some references may be changed by the reload operation).
    module_tree = _get_tree_references_to_reset_recursively(module, module.__name__)

    new_module = importlib.reload(module)
    _reset_item_recursively(module, module_tree, new_module)


def _update_referrers(item, new_item):
    refs = gc.get_referrers(item)

    weak_ref_item = ref(item)
    for coll in refs:
        if type(coll) == dict:
            enumerator = coll.keys()
        elif type(coll) == list:
            enumerator = range(len(coll))
        else:
            continue

        for key in enumerator:

            if weak_ref_item() is None:
                # No refs are left in the GC
                return

            if coll[key] is weak_ref_item():
                coll[key] = new_item

def _get_tree_references_to_reset_recursively(item, module_name, grayed_out_item_ids = None):
    if grayed_out_item_ids is None:
        grayed_out_item_ids = set()

    item_tree = dict()
    attr_names = set(dir(item)) - _readonly_attrs
    for sub_item_name in attr_names:

        sub_item = getattr(item, sub_item_name)
        item_tree[sub_item_name] = [sub_item, None]

        try:
            # Will work for classes and functions defined in that module.
            mod_name = sub_item.__module__
        except AttributeError:
            mod_name = None

        # If this item was defined within this module, deep-reset
        if (mod_name is None) or (mod_name != module_name) or (id(sub_item) in grayed_out_item_ids) \
                or isinstance(sub_item, EnumMeta):
            continue

        grayed_out_item_ids.add(id(sub_item))
        item_tree[sub_item_name][1] = \
            _get_tree_references_to_reset_recursively(sub_item, module_name, grayed_out_item_ids)

    return item_tree


def _reset_item_recursively(item, item_subtree, new_item):

    # Set children first so we don't lose the current references.
    if item_subtree is not None:
        for sub_item_name, (sub_item, sub_item_tree) in item_subtree.items():

            try:
                new_sub_item = getattr(new_item, sub_item_name)
            except AttributeError:
                # The item doesn't exist in the reloaded module. Ignore.
                continue

            try:
                # Set the item
                _reset_item_recursively(sub_item, sub_item_tree, new_sub_item)
            except Exception as ex:
                pass

    _update_referrers(item, new_item)

Original Answer

As written in @bobince’s answer, if there’s already a reference to that module in another module (especially if it was imported with the as keyword like import numpy as np), that instance will not be overwritten.

This proved quite problematic to me when applying tests that required a “clean-slate” state of the configuration modules, so I’ve written a function named reset_module that uses importlib‘s reload function and recursively overwrites all the declared module’s attributes. It has been tested with Python version 3.6.

import importlib
import inspect
from enum import EnumMeta

_readonly_attrs = {'__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__',
               '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__func__', '__ge__', '__get__',
               '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__',
               '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__',
               '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__',
               '__subclasshook__', '__weakref__', '__members__', '__mro__', '__itemsize__', '__isabstractmethod__',
               '__basicsize__', '__base__'}


def reset_module(module, inner_modules_also=True):
    """
    This function is a stronger form of importlib's `reload` function. What it does, is that aside from reloading a
    module, it goes to the old instance of the module, and sets all the (not read-only) attributes, functions and classes
    to be the reloaded-module's
    :param module: The module to reload (module reference, not the name)
    :param inner_modules_also: Whether to treat ths module as a package as well, and reload all the modules within it.
    """

    new_module = importlib.reload(module)

    reset_items = set()

    # For the case when the module is actually a package
    if inner_modules_also:
        submods = {submod for _, submod in inspect.getmembers(module)
                   if (type(submod).__name__ == 'module') and (submod.__package__.startswith(module.__name__))}
        for submod in submods:
            reset_module(submod, True)

    _reset_item_recursively(module, new_module, module.__name__, reset_items)


def _reset_item_recursively(item, new_item, module_name, reset_items=None):
    if reset_items is None:
        reset_items = set()

    attr_names = set(dir(item)) - _readonly_attrs

    for sitem_name in attr_names:

        sitem = getattr(item, sitem_name)
        new_sitem = getattr(new_item, sitem_name)

        try:
            # Set the item
            setattr(item, sitem_name, new_sitem)

            try:
                # Will work for classes and functions defined in that module.
                mod_name = sitem.__module__
            except AttributeError:
                mod_name = None

            # If this item was defined within this module, deep-reset
            if (mod_name is None) or (mod_name != module_name) or (id(sitem) in reset_items) \
                    or isinstance(sitem, EnumMeta):  # Deal with enums
                continue

            reset_items.add(id(sitem))
            _reset_item_recursively(sitem, new_sitem, module_name, reset_items)
        except Exception as ex:
            raise Exception(sitem_name) from ex

Note: Use with care! Using these on non-peripheral modules (modules that define externally-used classes, for example) might lead to internal problems in Python (such as pickling/un-pickling issues).


回答 16

对我而言,Abaqus就是这种方式。假设您的文件是Class_VerticesEdges.py

sys.path.append('D:\...\My Pythons')
if 'Class_VerticesEdges' in sys.modules:  
    del sys.modules['Class_VerticesEdges']
    print 'old module Class_VerticesEdges deleted'
from Class_VerticesEdges import *
reload(sys.modules['Class_VerticesEdges'])

for me for case of Abaqus it is the way it works. Imagine your file is Class_VerticesEdges.py

sys.path.append('D:\...\My Pythons')
if 'Class_VerticesEdges' in sys.modules:  
    del sys.modules['Class_VerticesEdges']
    print 'old module Class_VerticesEdges deleted'
from Class_VerticesEdges import *
reload(sys.modules['Class_VerticesEdges'])

回答 17

尝试在Sublime Text中重新加载某些内容时遇到了很多麻烦,但最终我可以编写此实用程序,根据代码在Sublime Text上重新加载模块 sublime_plugin.py用于重新加载模块重新加载模块。

下面的内容允许您从路径上带有空格的模块中重新加载模块,然后在重新加载之后,您可以照常导入。

def reload_module(full_module_name):
    """
        Assuming the folder `full_module_name` is a folder inside some
        folder on the python sys.path, for example, sys.path as `C:/`, and
        you are inside the folder `C:/Path With Spaces` on the file 
        `C:/Path With Spaces/main.py` and want to re-import some files on
        the folder `C:/Path With Spaces/tests`

        @param full_module_name   the relative full path to the module file
                                  you want to reload from a folder on the
                                  python `sys.path`
    """
    import imp
    import sys
    import importlib

    if full_module_name in sys.modules:
        module_object = sys.modules[full_module_name]
        module_object = imp.reload( module_object )

    else:
        importlib.import_module( full_module_name )

def run_tests():
    print( "\n\n" )
    reload_module( "Path With Spaces.tests.semantic_linefeed_unit_tests" )
    reload_module( "Path With Spaces.tests.semantic_linefeed_manual_tests" )

    from .tests import semantic_linefeed_unit_tests
    from .tests import semantic_linefeed_manual_tests

    semantic_linefeed_unit_tests.run_unit_tests()
    semantic_linefeed_manual_tests.run_manual_tests()

if __name__ == "__main__":
    run_tests()

如果是第一次运行,则应该加载该模块,但是如果以后可以再次使用该方法/功能run_tests(),它将重新加载测试文件。使用Sublime Text(Python 3.3.6)会发生很多事情,因为它的解释器永远不会关闭(除非您重新启动Sublime Text,即Python3.3解释器)。

I got a lot of trouble trying to reload something inside Sublime Text, but finally I could wrote this utility to reload modules on Sublime Text based on the code sublime_plugin.py uses to reload modules.

This below accepts you to reload modules from paths with spaces on their names, then later after reloading you can just import as you usually do.

def reload_module(full_module_name):
    """
        Assuming the folder `full_module_name` is a folder inside some
        folder on the python sys.path, for example, sys.path as `C:/`, and
        you are inside the folder `C:/Path With Spaces` on the file 
        `C:/Path With Spaces/main.py` and want to re-import some files on
        the folder `C:/Path With Spaces/tests`

        @param full_module_name   the relative full path to the module file
                                  you want to reload from a folder on the
                                  python `sys.path`
    """
    import imp
    import sys
    import importlib

    if full_module_name in sys.modules:
        module_object = sys.modules[full_module_name]
        module_object = imp.reload( module_object )

    else:
        importlib.import_module( full_module_name )

def run_tests():
    print( "\n\n" )
    reload_module( "Path With Spaces.tests.semantic_linefeed_unit_tests" )
    reload_module( "Path With Spaces.tests.semantic_linefeed_manual_tests" )

    from .tests import semantic_linefeed_unit_tests
    from .tests import semantic_linefeed_manual_tests

    semantic_linefeed_unit_tests.run_unit_tests()
    semantic_linefeed_manual_tests.run_manual_tests()

if __name__ == "__main__":
    run_tests()

If you run for the first time, this should load the module, but if later you can again the method/function run_tests() it will reload the tests files. With Sublime Text (Python 3.3.6) this happens a lot because its interpreter never closes (unless you restart Sublime Text, i.e., the Python3.3 interpreter).


回答 18

另一种方法是将模块导入功能中。这样,当函数完成时,模块将收集垃圾。

Another way could be to import the module in a function. This way when the function completes the module gets garbage collected.


如何导入其他Python文件?

问题:如何导入其他Python文件?

如何在Python中导入其他文件?

  1. 我到底该如何导入特定的python文件import file.py呢?
  2. 如何导入文件夹而不是特定文件?
  3. 我想根据用户输入在运行时动态加载Python文件。
  4. 我想知道如何从文件中仅加载一个特定部分。

例如,在main.py我有:

from extra import * 

尽管这给了我中的所有定义extra.py,但也许我只想要一个定义:

def gap():
    print
    print

我要从import语句中添加什么?gapextra.py

How do I import other files in Python?

  1. How exactly can I import a specific python file like import file.py?
  2. How can I import a folder instead of a specific file?
  3. I want to load a Python file dynamically at runtime, based on user input.
  4. I want to know how to load just one specific part from the file.

For example, in main.py I have:

from extra import * 

Although this gives me all the definitions in extra.py, when maybe all I want is a single definition:

def gap():
    print
    print

What do I add to the import statement to just get gap from extra.py?


回答 0

importlib已添加到Python 3中,以编程方式导入模块。它只是一个包装__import__,请参阅文档

import importlib

moduleName = input('Enter module name:')
importlib.import_module(moduleName)

注意:.py扩展名应从中删除moduleName。该函数还package为相对导入定义了一个参数。


更新:以下答案已过时。使用上面的最新替代方法。

  1. 只是import file没有’.py’扩展名。

  2. 您可以通过添加一个名为的空文件来将文件夹标记为包__init__.py

  3. 您可以使用该__import__功能。它以模块名称作为字符串。(同样:模块名称不带“ .py”扩展名。)

    pmName = input('Enter module name:')
    pm = __import__(pmName)
    print(dir(pm))
    

    输入help(__import__)以获取更多详细信息。

importlib was added to Python 3 to programmatically import a module. It is just a wrapper around __import__, see the docs.

import importlib

moduleName = input('Enter module name:')
importlib.import_module(moduleName)

Note: the .py extension should be removed from moduleName. The function also defines a package argument for relative imports.


Update: Answer below is outdated. Use the more recent alternative above.

  1. Just import file without the ‘.py’ extension.

  2. You can mark a folder as a package, by adding an empty file named __init__.py.

  3. You can use the __import__ function. It takes the module name as a string. (Again: module name without the ‘.py’ extension.)

    pmName = input('Enter module name:')
    pm = __import__(pmName)
    print(dir(pm))
    

    Type help(__import__) for more details.


回答 1

导入python文件的方法有很多,各有利弊。

不要只是匆忙地选择适合您的第一个导入策略,否则您将不得不在以后发现无法满足您的需要时重写代码库。

我将首先说明最简单的示例#1,然后将介绍最专业,最可靠的示例#7

示例1,使用python解释器导入python模块:

  1. 将其放在/home/el/foo/fox.py中:

    def what_does_the_fox_say():
      print("vixens cry")
  2. 进入python解释器:

    el@apollo:/home/el/foo$ python
    Python 2.7.3 (default, Sep 26 2013, 20:03:06) 
    >>> import fox
    >>> fox.what_does_the_fox_say()
    vixens cry
    >>> 

    您通过python解释器导入了fox,并what_does_the_fox_say()从fox.py中调用了python函数。

示例2,在脚本中使用execfile或(exec在Python 3中)在适当的位置执行另一个python文件:

  1. 将其放在/home/el/foo2/mylib.py中:

    def moobar():
      print("hi")
  2. 将其放在/home/el/foo2/main.py中:

    execfile("/home/el/foo2/mylib.py")
    moobar()
  3. 运行文件:

    el@apollo:/home/el/foo$ python main.py
    hi

    功能moobar是从mylib.py导入的,并在main.py中可用

示例3,从…使用…导入…功能:

  1. 将其放在/home/el/foo3/chekov.py中:

    def question():
      print "where are the nuclear wessels?"
  2. 将其放在/home/el/foo3/main.py中:

    from chekov import question
    question()
  3. 像这样运行它:

    el@apollo:/home/el/foo3$ python main.py 
    where are the nuclear wessels?

    如果您在chekov.py中定义了其他函数,除非您定义了这些函数,否则它们将不可用。 import *

示例4,如果导入的riaa.py与导入的文件位于不同的文件位置

  1. 将其放在/home/el/foo4/stuff/riaa.py中:

    def watchout():
      print "computers are transforming into a noose and a yoke for humans"
  2. 将其放在/home/el/foo4/main.py中:

    import sys 
    import os
    sys.path.append(os.path.abspath("/home/el/foo4/stuff"))
    from riaa import *
    watchout()
  3. 运行:

    el@apollo:/home/el/foo4$ python main.py 
    computers are transforming into a noose and a yoke for humans

    那会从另一个目录导入外部文件中的所有内容。

示例5,使用 os.system("python yourfile.py")

import os
os.system("python yourfile.py")

示例6,通过piggy带python startuphook导入文件:

更新:此示例曾经同时适用于python2和3,但现在仅适用于python2。python3摆脱了此用户启动钩子功能集,因为它被低技能的python库编写者滥用,使用它在所有用户定义的程序之前不礼貌地将其代码注入到全局命名空间中。如果您希望此功能适用于python3,则必须变得更有创意。如果我告诉您如何做,python开发人员也会禁用该功能集,因此您是一个人。

参见:https : //docs.python.org/2/library/user.html

将此代码放入您的主目录中 ~/.pythonrc.py

class secretclass:
    def secretmessage(cls, myarg):
        return myarg + " is if.. up in the sky, the sky"
    secretmessage = classmethod( secretmessage )

    def skycake(cls):
        return "cookie and sky pie people can't go up and "
    skycake = classmethod( skycake )

将此代码放入您的main.py(可以在任何地方):

import user
msg = "The only way skycake tates good" 
msg = user.secretclass.secretmessage(msg)
msg += user.secretclass.skycake()
print(msg + " have the sky pie! SKYCAKE!")

运行它,您应该获得以下信息:

$ python main.py
The only way skycake tates good is if.. up in the sky, 
the skycookie and sky pie people can't go up and  have the sky pie! 
SKYCAKE!

如果您在这里遇到错误:ModuleNotFoundError: No module named 'user'这意味着您正在使用python3,默认情况下会禁用启动钩。

值得一提的是:https : //github.com/docwhat/homedir-examples/blob/master/python-commandline/.pythonrc.py随便 发送。

示例7,最健壮:使用裸导入命令在python中导入文件:

  1. 建立一个新目录 /home/el/foo5/
  2. 建立一个新目录 /home/el/foo5/herp
  3. 制作一个以__init__.pyherp 命名的空文件:

    el@apollo:/home/el/foo5/herp$ touch __init__.py
    el@apollo:/home/el/foo5/herp$ ls
    __init__.py
  4. 新建一个目录/ home / el / foo5 / herp / derp

  5. 在derp下,制作另一个__init__.py文件:

    el@apollo:/home/el/foo5/herp/derp$ touch __init__.py
    el@apollo:/home/el/foo5/herp/derp$ ls
    __init__.py
  6. 在/ home / el / foo5 / herp / derp下,创建一个名为yolo.pyPut this 的新文件:

    def skycake():
      print "SkyCake evolves to stay just beyond the cognitive reach of " +
      "the bulk of men. SKYCAKE!!"
  7. 关键时刻,创建新文件/home/el/foo5/main.py,并将其放入其中;

    from herp.derp.yolo import skycake
    skycake()
  8. 运行:

    el@apollo:/home/el/foo5$ python main.py
    SkyCake evolves to stay just beyond the cognitive reach of the bulk 
    of men. SKYCAKE!!

    __init__.py文件会通知python解释器开发人员打算将此目录作为可导入包。

如果您想查看我的帖子,如何在目录下包含所有.py文件,请参见此处:https : //stackoverflow.com/a/20753073/445131

There are many ways to import a python file, all with their pros and cons.

Don’t just hastily pick the first import strategy that works for you or else you’ll have to rewrite the codebase later on when you find it doesn’t meet your needs.

I’ll start out explaining the easiest example #1, then I’ll move toward the most professional and robust example #7

Example 1, Import a python module with python interpreter:

  1. Put this in /home/el/foo/fox.py:

    def what_does_the_fox_say():
      print("vixens cry")
    
  2. Get into the python interpreter:

    el@apollo:/home/el/foo$ python
    Python 2.7.3 (default, Sep 26 2013, 20:03:06) 
    >>> import fox
    >>> fox.what_does_the_fox_say()
    vixens cry
    >>> 
    

    You imported fox through the python interpreter, invoked the python function what_does_the_fox_say() from within fox.py.

Example 2, Use execfile or (exec in Python 3) in a script to execute the other python file in place:

  1. Put this in /home/el/foo2/mylib.py:

    def moobar():
      print("hi")
    
  2. Put this in /home/el/foo2/main.py:

    execfile("/home/el/foo2/mylib.py")
    moobar()
    
  3. run the file:

    el@apollo:/home/el/foo$ python main.py
    hi
    

    The function moobar was imported from mylib.py and made available in main.py

Example 3, Use from … import … functionality:

  1. Put this in /home/el/foo3/chekov.py:

    def question():
      print "where are the nuclear wessels?"
    
  2. Put this in /home/el/foo3/main.py:

    from chekov import question
    question()
    
  3. Run it like this:

    el@apollo:/home/el/foo3$ python main.py 
    where are the nuclear wessels?
    

    If you defined other functions in chekov.py, they would not be available unless you import *

Example 4, Import riaa.py if it’s in a different file location from where it is imported

  1. Put this in /home/el/foo4/stuff/riaa.py:

    def watchout():
      print "computers are transforming into a noose and a yoke for humans"
    
  2. Put this in /home/el/foo4/main.py:

    import sys 
    import os
    sys.path.append(os.path.abspath("/home/el/foo4/stuff"))
    from riaa import *
    watchout()
    
  3. Run it:

    el@apollo:/home/el/foo4$ python main.py 
    computers are transforming into a noose and a yoke for humans
    

    That imports everything in the foreign file from a different directory.

Example 5, use os.system("python yourfile.py")

import os
os.system("python yourfile.py")

Example 6, import your file via piggybacking the python startuphook:

Update: This example used to work for both python2 and 3, but now only works for python2. python3 got rid of this user startuphook feature set because it was abused by low-skill python library writers, using it to impolitely inject their code into the global namespace, before all user-defined programs. If you want this to work for python3, you’ll have to get more creative. If I tell you how to do it, python developers will disable that feature set as well, so you’re on your own.

See: https://docs.python.org/2/library/user.html

Put this code into your home directory in ~/.pythonrc.py

class secretclass:
    def secretmessage(cls, myarg):
        return myarg + " is if.. up in the sky, the sky"
    secretmessage = classmethod( secretmessage )

    def skycake(cls):
        return "cookie and sky pie people can't go up and "
    skycake = classmethod( skycake )

Put this code into your main.py (can be anywhere):

import user
msg = "The only way skycake tates good" 
msg = user.secretclass.secretmessage(msg)
msg += user.secretclass.skycake()
print(msg + " have the sky pie! SKYCAKE!")

Run it, you should get this:

$ python main.py
The only way skycake tates good is if.. up in the sky, 
the skycookie and sky pie people can't go up and  have the sky pie! 
SKYCAKE!

If you get an error here: ModuleNotFoundError: No module named 'user' then it means you’re using python3, startuphooks are disabled there by default.

Credit for this jist goes to: https://github.com/docwhat/homedir-examples/blob/master/python-commandline/.pythonrc.py Send along your up-boats.

Example 7, Most Robust: Import files in python with the bare import command:

  1. Make a new directory /home/el/foo5/
  2. Make a new directory /home/el/foo5/herp
  3. Make an empty file named __init__.py under herp:

    el@apollo:/home/el/foo5/herp$ touch __init__.py
    el@apollo:/home/el/foo5/herp$ ls
    __init__.py
    
  4. Make a new directory /home/el/foo5/herp/derp

  5. Under derp, make another __init__.py file:

    el@apollo:/home/el/foo5/herp/derp$ touch __init__.py
    el@apollo:/home/el/foo5/herp/derp$ ls
    __init__.py
    
  6. Under /home/el/foo5/herp/derp make a new file called yolo.py Put this in there:

    def skycake():
      print "SkyCake evolves to stay just beyond the cognitive reach of " +
      "the bulk of men. SKYCAKE!!"
    
  7. The moment of truth, Make the new file /home/el/foo5/main.py, put this in there;

    from herp.derp.yolo import skycake
    skycake()
    
  8. Run it:

    el@apollo:/home/el/foo5$ python main.py
    SkyCake evolves to stay just beyond the cognitive reach of the bulk 
    of men. SKYCAKE!!
    

    The empty __init__.py file communicates to the python interpreter that the developer intends this directory to be an importable package.

If you want to see my post on how to include ALL .py files under a directory see here: https://stackoverflow.com/a/20753073/445131


回答 2

要在“运行时”以已知名称导入特定的Python文件:

import os
import sys

scriptpath = "../Test/"

# Add the directory containing your module to the Python path (wants absolute paths)
sys.path.append(os.path.abspath(scriptpath))

# Do the import
import MyModule

To import a specific Python file at ‘runtime’ with a known name:

import os
import sys

scriptpath = "../Test/"

# Add the directory containing your module to the Python path (wants absolute paths)
sys.path.append(os.path.abspath(scriptpath))

# Do the import
import MyModule

回答 3

您没有很多复杂的方法可以将python文件从一个文件夹导入到另一个文件夹。只需创建一个__init__.py文件,以声明此文件夹为python软件包,然后转到要导入的主机文件即可,只需键入

from root.parent.folder.file import variable, class, whatever

You do not have many complex methods to import a python file from one folder to another. Just create a __init__.py file to declare this folder is a python package and then go to your host file where you want to import just type

from root.parent.folder.file import variable, class, whatever


回答 4

导入文档..-链接以供参考

__init__.py需要这些文件才能使Python将目录视为包含软件包的目录,这样做是为了防止具有通用名称(例如字符串)的目录无意间隐藏了稍后在模块搜索路径中出现的有效模块。

__init__.py可以只是一个空文件,但也可以执行包的初始化代码或设置__all__变量。

mydir/spam/__init__.py
mydir/spam/module.py
import spam.module
or
from spam import module

Import doc .. — Link for reference

The __init__.py files are required to make Python treat the directories as containing packages, this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path.

__init__.py can just be an empty file, but it can also execute initialization code for the package or set the __all__ variable.

mydir/spam/__init__.py
mydir/spam/module.py
import spam.module
or
from spam import module

回答 5

第一种情况:您要在file A.py中导入文件B.py,这两个文件位于同一文件夹中,如下所示:

. 
├── A.py 
└── B.py

您可以在file中执行此操作B.py

import A

要么

from A import *

要么

from A import THINGS_YOU_WANT_TO_IMPORT_IN_A

然后,您将可以使用文件A.py中文件的所有功能B.py


第二种情况:您要在file folder/A.py中导入文件B.py,这两个文件不在同一文件夹中,如下所示:

.
├── B.py
└── folder
     └── A.py

您可以在文件B中执行此操作:

import folder.A

要么

from folder.A import *

要么

from folder.A import THINGS_YOU_WANT_TO_IMPORT_IN_A

然后,您将可以使用文件A.py中文件的所有功能B.py


摘要:在第一种情况下,file A.py是您在file中导入的模块,B.py使用了语法import module_name。在第二种情况下,使用的语法folder是包含模块的软件包。A.pyimport package_name.module_name

有关软件包和模块的更多信息,请参考此链接

First case: You want to import file A.py in file B.py, these two files are in the same folder, like this:

. 
├── A.py 
└── B.py

You can do this in file B.py:

import A

or

from A import *

or

from A import THINGS_YOU_WANT_TO_IMPORT_IN_A

Then you will be able to use all the functions of file A.py in file B.py


Second case: You want to import file folder/A.py in file B.py, these two files are not in the same folder, like this:

.
├── B.py
└── folder
     └── A.py

You can do this in file B:

import folder.A

or

from folder.A import *

or

from folder.A import THINGS_YOU_WANT_TO_IMPORT_IN_A

Then you will be able to use all the functions of file A.py in file B.py


Summary: In the first case, file A.py is a module that you imports in file B.py, you used the syntax import module_name. In the second case, folder is the package that contains the module A.py, you used the syntax import package_name.module_name.

For more info on packages and modules, consult this link.


回答 6

from file import function_name  ######## Importing specific function
function_name()                 ######## Calling function

import file              ######## Importing whole package
file.function1_name()    ######## Calling function
file.function2_name()    ######## Calling function

这是到目前为止我已经了解的两种简单方法,请确保要导入为库的“ file.py”文件仅存在于当前目录中。

from file import function_name  ######## Importing specific function
function_name()                 ######## Calling function

and

import file              ######## Importing whole package
file.function1_name()    ######## Calling function
file.function2_name()    ######## Calling function

Here are the two simple ways I have understood by now and make sure your “file.py” file which you want to import as a library is present in your current directory only.


回答 7

如果定义的函数在文件中x.py

def greet():
    print('Hello! How are you?')

在要导入函数的文件中,编写以下代码:

from x import greet

如果您不希望将所有功能导入文件中,这将很有用。

If the function defined is in a file x.py:

def greet():
    print('Hello! How are you?')

In the file where you are importing the function, write this:

from x import greet

This is useful if you do not wish to import all the functions in a file.


回答 8

导入.py文件的最佳方法是通过__init__.py。最简单的操作是__init__.py在your.py文件所在的目录中创建一个名为空文件。

Mike Grouchy的这篇文章很好地解释了__init__.py它在制作,导入和设置python包中的用途。

the best way to import .py files is by way of __init__.py. the simplest thing to do, is to create an empty file named __init__.py in the same directory that your.py file is located.

this post by Mike Grouchy is a great explanation of __init__.py and its use for making, importing, and setting up python packages.


回答 9

我的导入方式是导入文件并使用其名称的缩写。

import DoStuff.py as DS
DS.main()

不要忘记您的导入文件必须以.py扩展名命名

How I import is import the file and use shorthand of it’s name.

import DoStuff.py as DS
DS.main()

Don’t forget that your importing file MUST BE named with .py extension


回答 10

我想在其他地方加一个不太清楚的注释。在模块/软件包内部,从文件加载时,模块/软件包名称必须带有前缀mymodule。想象一下mymodule这样的布局:

/main.py
/mymodule
    /__init__.py
    /somefile.py
    /otherstuff.py

从内容中加载somefile.py/ 时应如下所示:otherstuff.py__init__.py

from mymodule.somefile import somefunc
from mymodule.otherstuff import otherfunc

I’d like to add this note I don’t very clearly elsewhere; inside a module/package, when loading from files, the module/package name must be prefixed with the mymodule. Imagine mymodule being layout like this:

/main.py
/mymodule
    /__init__.py
    /somefile.py
    /otherstuff.py

When loading somefile.py/otherstuff.py from __init__.py the contents should look like:

from mymodule.somefile import somefunc
from mymodule.otherstuff import otherfunc

回答 11

如果要导入的模块不在子目录中,请尝试以下操作并app.py从最深的公共父目录中运行:

目录结构:

/path/to/common_dir/module/file.py
/path/to/common_dir/application/app.py
/path/to/common_dir/application/subpath/config.json

在中app.py,将客户端路径附加到sys.path:

import os, sys, inspect

sys.path.append(os.getcwd())
from module.file import MyClass
instance = MyClass()

可选(如果您加载例如configs)(对于我的用例,检查似乎是最可靠的一种)

# Get dirname from inspect module
filename = inspect.getframeinfo(inspect.currentframe()).filename
dirname = os.path.dirname(os.path.abspath(filename))
MY_CONFIG = os.path.join(dirname, "subpath/config.json")

user@host:/path/to/common_dir$ python3 application/app.py

此解决方案在cli和PyCharm中都对我有效。

In case the module you want to import is not in a sub-directory, then try the following and run app.py from the deepest common parent directory:

Directory Structure:

/path/to/common_dir/module/file.py
/path/to/common_dir/application/app.py
/path/to/common_dir/application/subpath/config.json

In app.py, append path of client to sys.path:

import os, sys, inspect

sys.path.append(os.getcwd())
from module.file import MyClass
instance = MyClass()

Optional (If you load e.g. configs) (Inspect seems to be the most robust one for my use cases)

# Get dirname from inspect module
filename = inspect.getframeinfo(inspect.currentframe()).filename
dirname = os.path.dirname(os.path.abspath(filename))
MY_CONFIG = os.path.join(dirname, "subpath/config.json")

Run

user@host:/path/to/common_dir$ python3 application/app.py

This solution works for me in cli, as well as PyCharm.


回答 12

有几种方法可以包含名称为abc.py的python脚本

  1. 例如,如果您的文件名为abc.py(导入abc),则限制是文件应位于与您的调用python脚本相同的位置。

导入abc

  1. 例如,如果您的python文件位于Windows文件夹中。Windows文件夹位于您调用Python脚本的位置。

从文件夹导入abc

  1. 如果abc.py脚本在文件夹中存在的Insider Internal_folder内部可用

从folder.internal_folder导入abc

  1. 如上文James所述,如果您的文件位于某个固定位置

import os
import sys
scriptpath =“ ../Test/MyModule.py”
sys.path.append(os.path.abspath(scriptpath))
import MyModule

如果您的python脚本已更新并且不想上传,请使用这些语句进行自动刷新。奖金:)

%load_ext autoreload 
%autoreload 2

There are couple of ways of including your python script with name abc.py

  1. e.g. if your file is called abc.py (import abc) Limitation is that your file should be present in the same location where your calling python script is.

import abc

  1. e.g. if your python file is inside the Windows folder. Windows folder is present at the same location where your calling python script is.

from folder import abc

  1. Incase abc.py script is available insider internal_folder which is present inside folder

from folder.internal_folder import abc

  1. As answered by James above, in case your file is at some fixed location

import os
import sys
scriptpath = “../Test/MyModule.py”
sys.path.append(os.path.abspath(scriptpath))
import MyModule

In case your python script gets updated and you don’t want to upload – use these statements for auto refresh. Bonus :)

%load_ext autoreload 
%autoreload 2

回答 13

只是为了将python文件导入另一个python文件

可以说我有一个具有显示功能的helper.py python文件,

def display():
    print("I'm working sundar gsv")

现在在app.py中,您可以使用显示功能,

import helper
helper.display()

输出,

I'm working sundar gsv

注意:无需指定.py扩展名。

Just to import python file in another python file

lets say I have helper.py python file which has a display function like,

def display():
    print("I'm working sundar gsv")

Now in app.py, you can use the display function,

import helper
helper.display()

The output,

I'm working sundar gsv

NOTE: No need to specify the .py extension.


回答 14

这听起来很疯狂,但是如果您只是要为其创建包装脚本,则可以仅创建指向要导入文件的符号链接。

This may sound crazy but you can just create a symbolic link to the file you want to import if you’re just creating a wrapper script to it.


回答 15

您也可以这样做: from filename import something

示例:from client import Client 请注意,您不需要.py .pyw .pyui扩展名。

You can also do this: from filename import something

example: from client import Client Note that you do not need the .py .pyw .pyui extension.


回答 16

这就是我从python文件中调用函数的方式,这对我来说可以灵活地调用任何函数。

import os, importlib, sys

def callfunc(myfile, myfunc, *args):
    pathname, filename = os.path.split(myfile)
    sys.path.append(os.path.abspath(pathname))
    modname = os.path.splitext(filename)[0]
    mymod = importlib.import_module(modname)
    result = getattr(mymod, myfunc)(*args)
    return result

result = callfunc("pathto/myfile.py", "myfunc", arg1, arg2)

This is how I did to call a function from a python file, that is flexible for me to call any functions.

import os, importlib, sys

def callfunc(myfile, myfunc, *args):
    pathname, filename = os.path.split(myfile)
    sys.path.append(os.path.abspath(pathname))
    modname = os.path.splitext(filename)[0]
    mymod = importlib.import_module(modname)
    result = getattr(mymod, myfunc)(*args)
    return result

result = callfunc("pathto/myfile.py", "myfunc", arg1, arg2)

回答 17

如上所述,有很多方法,但是我发现我只想导入他文件的内容,而不想要写行和输入其他模块。因此,我想出了一种方法来获取文件的内容,即使使用点语法(file.property)也是如此,而不是将导入的文件与您的文件合并。
首先,这是我要导入的文件,data.py

    testString= "A string literal to import and test with"


注意:您可以改用.txt扩展名。
在中mainfile.py,首先打开并获取内容。

    #!usr/bin/env python3
    Data=open('data.txt','r+').read()

现在,您已将内容作为字符串保存,但是尝试访问data.testString将导致错误,就像该类data的实例一样str,即使它确实具有属性testString,也无法实现您期望的效果。
接下来,创建一个类。例如(双关语意图),ImportedFile

    class ImportedFile:

并放入其中(带有适当的缩进):

    exec(data)


最后,data像这样重新分配:

    data=ImportedFile()

就是这样!就像访问其他模块一样进行访问,print(data.testString)将在控制台上输入内容A string literal to import and test with
但是,如果您from mod import *只想删除类,实例分配并取消缩进,则等效于exec

希望这会
有所帮助:)-Benji

There are many ways, as listed above, but I find that I just want to import he contents of a file, and don’t want to have to write lines and lines and have to import other modules. So, I came up with a way to get the contents of a file, even with the dot syntax (file.property) as opposed to merging the imported file with yours.
First of all, here is my file which I’ll import, data.py

    testString= "A string literal to import and test with"


Note: You could use the .txt extension instead.
In mainfile.py, start by opening and getting the contents.

    #!usr/bin/env python3
    Data=open('data.txt','r+').read()

Now you have the contents as a string, but trying to access data.testString will cause an error, as data is an instance of the str class, and even if it does have a property testString it will not do what you expected.
Next, create a class. For instance (pun intended), ImportedFile

    class ImportedFile:

And put this into it (with the appropriate indentation):

    exec(data)


And finally, re-assign data like so:

    data=ImportedFile()

And that’s it! Just access like you would for any-other module, typing print(data.testString) will print to the console A string literal to import and test with.
If, however, you want the equivalent of from mod import * just drop the class, instance assignment, and de-dent the exec.

Hope this helps:)
-Benji


回答 18

Python的一个非常未知的功能是能够导入zip文件:

library.zip
|-library
|--__init__.py

__init__.py软件包的文件包含以下内容:

def dummy():
    print 'Testing things out...'

我们可以编写另一个脚本,该脚本可以从zip存档中导入包。仅需要将zip文件添加到sys.path。

import sys
sys.path.append(r'library.zip')

import library

def run():
    library.dummy()

run()

One very unknown feature of Python is the ability to import zip files:

library.zip
|-library
|--__init__.py

The file __init__.py of the package contains the following:

def dummy():
    print 'Testing things out...'

We can write another script which can import a package from the zip archive. It is only necessary to add the zip file to the sys.path.

import sys
sys.path.append(r'library.zip')

import library

def run():
    library.dummy()

run()

从相对路径导入模块

问题:从相对路径导入模块

给定相对路径,如何导入Python模块?

例如,如果dirFoo包含Foo.pydirBar,和dirBar包含Bar.py,我怎么导入Bar.pyFoo.py

这是一个视觉表示:

dirFoo\
    Foo.py
    dirBar\
        Bar.py

Foo希望包含Bar,但重组文件夹层次结构不是一种选择。

How do I import a Python module given its relative path?

For example, if dirFoo contains Foo.py and dirBar, and dirBar contains Bar.py, how do I import Bar.py into Foo.py?

Here’s a visual representation:

dirFoo\
    Foo.py
    dirBar\
        Bar.py

Foo wishes to include Bar, but restructuring the folder hierarchy is not an option.


回答 0

假设您的两个目录都是真实的Python包(__init__.py文件中确实有文件),那么这是一个相对于脚本位置包含模块的安全解决方案。

我假设您想这样做,因为您需要在脚本中包括一组模块。我在多个产品的生产环境中使用了此功能,并在许多特殊情况下工作,例如:从另一个目录调用或使用python执行的脚本执行而不是打开新的解释器。

 import os, sys, inspect
 # realpath() will make your script run, even if you symlink it :)
 cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]))
 if cmd_folder not in sys.path:
     sys.path.insert(0, cmd_folder)

 # Use this if you want to include modules from a subfolder
 cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"subfolder")))
 if cmd_subfolder not in sys.path:
     sys.path.insert(0, cmd_subfolder)

 # Info:
 # cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ !!!
 # __file__ fails if the script is called in different ways on Windows.
 # __file__ fails if someone does os.chdir() before.
 # sys.argv[0] also fails, because it doesn't not always contains the path.

另外,这种方法确实可以让您强制Python使用模块,而不是系统上安装的模块。

警告!我真的不知道当前模块在egg文件中时会发生什么。它也可能失败。

Assuming that both your directories are real Python packages (do have the __init__.py file inside them), here is a safe solution for inclusion of modules relatively to the location of the script.

I assume that you want to do this, because you need to include a set of modules with your script. I use this in production in several products and works in many special scenarios like: scripts called from another directory or executed with python execute instead of opening a new interpreter.

 import os, sys, inspect
 # realpath() will make your script run, even if you symlink it :)
 cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]))
 if cmd_folder not in sys.path:
     sys.path.insert(0, cmd_folder)

 # Use this if you want to include modules from a subfolder
 cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"subfolder")))
 if cmd_subfolder not in sys.path:
     sys.path.insert(0, cmd_subfolder)

 # Info:
 # cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ !!!
 # __file__ fails if the script is called in different ways on Windows.
 # __file__ fails if someone does os.chdir() before.
 # sys.argv[0] also fails, because it doesn't not always contains the path.

As a bonus, this approach does let you force Python to use your module instead of the ones installed on the system.

Warning! I don’t really know what is happening when current module is inside an egg file. It probably fails too.


回答 1

确保dirBar具有__init__.py文件-这会将目录创建到Python包中。

Be sure that dirBar has the __init__.py file — this makes a directory into a Python package.


回答 2

您也可以将子目录添加到Python路径中,以便将其作为普通脚本导入。

import sys
sys.path.insert(0, <path to dirFoo>)
import Bar

You could also add the subdirectory to your Python path so that it imports as a normal script.

import sys
sys.path.insert(0, <path to dirFoo>)
import Bar

回答 3

import os
import sys
lib_path = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'lib'))
sys.path.append(lib_path)

import mymodule
import os
import sys
lib_path = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'lib'))
sys.path.append(lib_path)

import mymodule

回答 4

只需执行简单的操作即可从其他文件夹导入.py文件。

假设您有一个目录,例如:

lib/abc.py

然后只需将一个空文件保留在lib文件夹中,命名为

__init__.py

然后用

from lib.abc import <Your Module name>

__init__.py文件保留在导入模块层次结构的每个文件夹中。

Just do simple things to import the .py file from a different folder.

Let’s say you have a directory like:

lib/abc.py

Then just keep an empty file in lib folder as named

__init__.py

And then use

from lib.abc import <Your Module name>

Keep the __init__.py file in every folder of the hierarchy of the import module.


回答 5

如果您以这种方式构建项目:

src\
  __init__.py
  main.py
  dirFoo\
    __init__.py
    Foo.py
  dirBar\
    __init__.py
    Bar.py

然后从Foo.py您应该可以执行以下操作:

import dirFoo.Foo

要么:

from dirFoo.Foo import FooObject

根据Tom的评论,这确实要求src可以通过site_packages或您的搜索路径访问该文件夹。而且,正如他所提到的,__init__.py当您首次在该包/目录中导入模块时,它是隐式导入的。通常__init__.py只是一个空文件。

If you structure your project this way:

src\
  __init__.py
  main.py
  dirFoo\
    __init__.py
    Foo.py
  dirBar\
    __init__.py
    Bar.py

Then from Foo.py you should be able to do:

import dirFoo.Foo

Or:

from dirFoo.Foo import FooObject

Per Tom’s comment, this does require that the src folder is accessible either via site_packages or your search path. Also, as he mentions, __init__.py is implicitly imported when you first import a module in that package/directory. Typically __init__.py is simply an empty file.


回答 6

最简单的方法是使用sys.path.append()。

但是,您可能也对imp模块感兴趣。它提供对内部导入功能的访问。

# mod_name is the filename without the .py/.pyc extention
py_mod = imp.load_source(mod_name,filename_path) # Loads .py file
py_mod = imp.load_compiled(mod_name,filename_path) # Loads .pyc file 

当您不知道模块名称时,可以使用它来动态加载模块。

过去我曾使用它来创建应用程序的插件类型接口,用户可以在其中编写具有应用程序特定功能的脚本,然后将其脚本放置在特定目录中。

此外,这些功能可能会很有用:

imp.find_module(name[, path])
imp.load_module(name, file, pathname, description)

The easiest method is to use sys.path.append().

However, you may be also interested in the imp module. It provides access to internal import functions.

# mod_name is the filename without the .py/.pyc extention
py_mod = imp.load_source(mod_name,filename_path) # Loads .py file
py_mod = imp.load_compiled(mod_name,filename_path) # Loads .pyc file 

This can be used to load modules dynamically when you don’t know a module’s name.

I’ve used this in the past to create a plugin type interface to an application, where the user would write a script with application specific functions, and just drop thier script in a specific directory.

Also, these functions may be useful:

imp.find_module(name[, path])
imp.load_module(name, file, pathname, description)

回答 7

这是相关的PEP:

http://www.python.org/dev/peps/pep-0328/

特别是,假定dirFoo是dirBar的目录。

在dirFoo \ Foo.py中:

from ..dirBar import Bar

This is the relevant PEP:

http://www.python.org/dev/peps/pep-0328/

In particular, presuming dirFoo is a directory up from dirBar…

In dirFoo\Foo.py:

from ..dirBar import Bar

回答 8

不对脚本进行任何修改的最简单方法是设置PYTHONPATH环境变量。由于sys.path是从以下位置初始化的:

  1. 包含输入脚本的目录(或当前目录)。
  2. PYTHONPATH(目录名称列表,语法与shell变量PATH相同)。
  3. 取决于安装的默认值。

赶紧跑:

export PYTHONPATH=/absolute/path/to/your/module

您的sys.path将包含以上路径,如下所示:

print sys.path

['', '/absolute/path/to/your/module', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/ubuntuone-client', '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', '/usr/lib/python2.7/dist-packages/ubuntuone-couch', '/usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol']

The easiest way without any modification to your script is to set PYTHONPATH environment variable. Because sys.path is initialized from these locations:

  1. The directory containing the input script (or the current directory).
  2. PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
  3. The installation-dependent default.

Just run:

export PYTHONPATH=/absolute/path/to/your/module

You sys.path will contains above path, as show below:

print sys.path

['', '/absolute/path/to/your/module', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/ubuntuone-client', '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', '/usr/lib/python2.7/dist-packages/ubuntuone-couch', '/usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol']

回答 9

我认为最好的选择是将__ init __.py放在文件夹中,然后使用

from dirBar.Bar import *

不建议使用sys.path.append(),因为如果您使用与现有python包相同的文件名,则可能会出错。我还没有测试,但这将是模棱两可的。

In my opinion the best choice is to put __ init __.py in the folder and call the file with

from dirBar.Bar import *

It is not recommended to use sys.path.append() because something might gone wrong if you use the same file name as the existing python package. I haven’t test that but that will be ambiguous.


回答 10

Linux用户的快捷方式

如果您只是在修改而不关心部署问题,则可以使用符号链接(假设文件系统支持它)使模块或程序包直接在请求模块的文件夹中可见。

ln -s (path)/module_name.py

要么

ln -s (path)/package_name

注意:“模块”是带有.py扩展名的任何文件,“包”是包含该文件的任何文件夹__init__.py(可以是空文件)。从使用的角度来看,模块和程序包是相同的-都按照import命令的要求公开了它们包含的“定义和语句” 。

请参阅:http : //docs.python.org/2/tutorial/modules.html

The quick-and-dirty way for Linux users

If you are just tinkering around and don’t care about deployment issues, you can use a symbolic link (assuming your filesystem supports it) to make the module or package directly visible in the folder of the requesting module.

ln -s (path)/module_name.py

or

ln -s (path)/package_name

Note: A “module” is any file with a .py extension and a “package” is any folder that contains the file __init__.py (which can be an empty file). From a usage standpoint, modules and packages are identical — both expose their contained “definitions and statements” as requested via the import command.

See: http://docs.python.org/2/tutorial/modules.html


回答 11

from .dirBar import Bar

代替:

from dirBar import Bar

以防万一可能会安装另一个dirBar并混淆foo.py阅读器。

from .dirBar import Bar

instead of:

from dirBar import Bar

just in case there could be another dirBar installed and confuse a foo.py reader.


回答 12

对于这种情况,要将Bar.py导入Foo.py,首先,将这些文件夹转换为Python包,如下所示:

dirFoo\
    __init__.py
    Foo.py
    dirBar\
        __init__.py
        Bar.py

然后我会在Foo.py中这样做:

from .dirBar import Bar

如果我希望命名空间看起来像Bar。不管,或

from . import dirBar

如果我想要命名空间dirBar.Bar。随便。如果您在dirBar包下有更多模块,则第二种情况很有用。

For this case to import Bar.py into Foo.py, first I’d turn these folders into Python packages like so:

dirFoo\
    __init__.py
    Foo.py
    dirBar\
        __init__.py
        Bar.py

Then I would do it like this in Foo.py:

from .dirBar import Bar

If I wanted the namespacing to look like Bar.whatever, or

from . import dirBar

If I wanted the namespacing dirBar.Bar.whatever. This second case is useful if you have more modules under the dirBar package.


回答 13

添加__init__.py文件:

dirFoo\
    Foo.py
    dirBar\
        __init__.py
        Bar.py

然后将此代码添加到Foo.py的开头:

import sys
sys.path.append('dirBar')
import Bar

Add an __init__.py file:

dirFoo\
    Foo.py
    dirBar\
        __init__.py
        Bar.py

Then add this code to the start of Foo.py:

import sys
sys.path.append('dirBar')
import Bar

回答 14

相对sys.path示例:

# /lib/my_module.py
# /src/test.py


if __name__ == '__main__' and __package__ is None:
    sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../lib')))
import my_module

基于答案。

Relative sys.path example:

# /lib/my_module.py
# /src/test.py


if __name__ == '__main__' and __package__ is None:
    sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../lib')))
import my_module

Based on this answer.


回答 15

好了,正如您提到的,通常您希望访问一个包含您的模块的文件夹,该模块相对于您运行主脚本的位置,因此您只需导入它们即可。

解:

我有脚本D:/Books/MyBooks.py和一些模块(如oldies.py)。我需要从子目录导入D:/Books/includes

import sys,site
site.addsitedir(sys.path[0] + '\\includes')
print (sys.path)  # Just verify it is there
import oldies

print('done')放在中oldies.py,以便您确认一切正常。这种方法始终有效,因为sys.path根据程序启动时初始化的Python定义,此列表的第一项path[0]是包含用于调用Python解释器的脚本的目录。

如果脚本目录不可用(例如,如果交互式调用解释器或从标准输入中读取脚本),path[0]则为空字符串,该字符串将引导Python首先搜索当前目录中的模块。请注意,作为的结果,在插入条目之前插入了脚本目录PYTHONPATH

Well, as you mention, usually you want to have access to a folder with your modules relative to where your main script is run, so you just import them.

Solution:

I have the script in D:/Books/MyBooks.py and some modules (like oldies.py). I need to import from subdirectory D:/Books/includes:

import sys,site
site.addsitedir(sys.path[0] + '\\includes')
print (sys.path)  # Just verify it is there
import oldies

Place a print('done') in oldies.py, so you verify everything is going OK. This way always works because by the Python definition sys.path as initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter.

If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first. Notice that the script directory is inserted before the entries inserted as a result of PYTHONPATH.


回答 16

只需使用即可: from Desktop.filename import something

例:

鉴于该文件是test.pydirectory目录中的 name Users/user/Desktop,并且将导入所有内容。

编码:

from Desktop.test import *

但是请确保__init__.py在该目录中创建一个名为“ ” 的空文件

Simply you can use: from Desktop.filename import something

Example:

given that the file is name test.py in directory Users/user/Desktop , and will import everthing.

the code:

from Desktop.test import *

But make sure you make an empty file called “__init__.py” in that directory


回答 17

另一种解决方案是安装py-require软件包,然后在Foo.py

import require
Bar = require('./dirBar/Bar')

Another solution would be to install the py-require package and then use the following in Foo.py

import require
Bar = require('./dirBar/Bar')

回答 18

这是一种使用相对路径从上一级导入文件的方法。

基本上,只需将工作目录上移某个级别(或任何相对位置),然后将其添加到您的路径中,然后再将工作目录移回其开始位置即可。

#to import from one level above:
cwd = os.getcwd()
os.chdir("..")
below_path =  os.getcwd()
sys.path.append(below_path)
os.chdir(cwd)

Here’s a way to import a file from one level above, using the relative path.

Basically, just move the working directory up a level (or any relative location), add that to your path, then move the working directory back where it started.

#to import from one level above:
cwd = os.getcwd()
os.chdir("..")
below_path =  os.getcwd()
sys.path.append(below_path)
os.chdir(cwd)

回答 19

我对python没有经验,所以如果我的话有什么错误,请告诉我。如果您的文件层次结构是这样排列的:

project\
    module_1.py 
    module_2.py

module_1.py定义了一个称为函数func_1()module_2.py

from module_1 import func_1

def func_2():
    func_1()

if __name__ == '__main__':
    func_2()

并且您python module_2.py在cmd中运行,它将按func_1()定义运行。通常,这就是我们导入相同层次结构文件的方式。但是当您from .module_1 import func_1输入时module_2.py,python解释器会说No module named '__main__.module_1'; '__main__' is not a package。因此,要解决此问题,我们只需保留所做的更改,然后将两个模块都移到一个程序包中,然后将第三个模块作为调用方运行即可module_2.py

project\
    package_1\
        module_1.py
        module_2.py
    main.py

main.py

from package_1.module_2 import func_2

def func_3():
    func_2()

if __name__ == '__main__':
    func_3()

而增加了的原因.之前module_1module_2.py是,如果我们不这样做,并运行main.py,Python解释器会说No module named 'module_1',这是一个有点棘手,module_1.py是旁边module_2.py。现在让我func_1()module_1.py做一些事情:

def func_1():
    print(__name__)

__name__记录谁调用func_1。现在,我们保留.之前的内容module_1,运行main.py,它将打印出来package_1.module_1,而不是module_1。它表明呼叫的func_1()对象与处于相同的层次结构main.py,这.意味着module_1与其module_2.py本身处于相同的层次结构。因此,如果没有点,main.py它将module_1在与自身相同的层次结构中进行识别package_1,它可以识别,但不能识别它的“下方”。

现在,让它变得有点复杂。您有一个,config.ini并且一个模块定义了一个函数来读取与“ main.py”相同的层次结构的函数。

project\
    package_1\
        module_1.py
        module_2.py
    config.py
    config.ini
    main.py

出于某些不可避免的原因,您必须使用调用它module_2.py,因此必须从上层结构导入。module_2.py

 import ..config
 pass

两点表示从上级结构导入(三个点访问上层而不是上层,依此类推)。现在运行main.py,解释器将说:ValueError:attempted relative import beyond top-level package。这里的“顶级程序包”是main.py。仅仅因为config.py在旁边main.py,它们处于相同的层次结构,config.py不在“下面” main.py,或者不在“前面” main.py,所以它超出了main.py。要解决此问题,最简单的方法是:

project\
    package_1\
        module_1.py
        module_2.py
    config.py
    config.ini
main.py

我认为这与安排项目文件层次结构的原理是一致的,您应该将具有不同功能的模块安排在不同的文件夹中,而仅在外部放置一个顶级调用方,然后可以随心所欲地导入。

I’m not experienced about python, so if there is any wrong in my words, just tell me. If your file hierarchy arranged like this:

project\
    module_1.py 
    module_2.py

module_1.py defines a function called func_1(), module_2.py:

from module_1 import func_1

def func_2():
    func_1()

if __name__ == '__main__':
    func_2()

and you run python module_2.py in cmd, it will do run what func_1() defines. That’s usually how we import same hierarchy files. But when you write from .module_1 import func_1 in module_2.py, python interpreter will say No module named '__main__.module_1'; '__main__' is not a package. So to fix this, we just keep the change we just make, and move both of the module to a package, and make a third module as a caller to run module_2.py.

project\
    package_1\
        module_1.py
        module_2.py
    main.py

main.py:

from package_1.module_2 import func_2

def func_3():
    func_2()

if __name__ == '__main__':
    func_3()

But the reason we add a . before module_1 in module_2.py is that if we don’t do that and run main.py, python interpreter will say No module named 'module_1', that’s a little tricky, module_1.py is right beside module_2.py. Now I let func_1() in module_1.py do something:

def func_1():
    print(__name__)

that __name__ records who calls func_1. Now we keep the . before module_1 , run main.py, it will print package_1.module_1, not module_1. It indicates that the one who calls func_1() is at the same hierarchy as main.py, the . imply that module_1 is at the same hierarchy as module_2.py itself. So if there isn’t a dot, main.py will recognize module_1 at the same hierarchy as itself, it can recognize package_1, but not what “under” it.

Now let’s make it a bit complicated. You have a config.ini and a module defines a function to read it at the same hierarchy as ‘main.py’.

project\
    package_1\
        module_1.py
        module_2.py
    config.py
    config.ini
    main.py

And for some unavoidable reason, you have to call it with module_2.py, so it has to import from upper hierarchy.module_2.py:

 import ..config
 pass

Two dots means import from upper hierarchy (three dots access upper than upper,and so on). Now we run main.py, the interpreter will say:ValueError:attempted relative import beyond top-level package. The “top-level package” at here is main.py. Just because config.py is beside main.py, they are at same hierarchy, config.py isn’t “under” main.py, or it isn’t “leaded” by main.py, so it is beyond main.py. To fix this, the simplest way is:

project\
    package_1\
        module_1.py
        module_2.py
    config.py
    config.ini
main.py

I think that is coincide with the principle of arrange project file hierarchy, you should arrange modules with different function in different folders, and just leave a top caller in the outside, and you can import how ever you want.


回答 20

这也可行,并且比使用该sys模块的任何事情都要简单得多:

with open("C:/yourpath/foobar.py") as f:
    eval(f.read())

This also works, and is much simpler than anything with the sys module:

with open("C:/yourpath/foobar.py") as f:
    eval(f.read())

回答 21

称我过于谨慎,但我想让我的便携式计算机更加便携,因为假设文件始终位于每台计算机上的同一位置是不安全的。我个人的代码首先查找文件路径。我使用Linux,所以我的看起来像这样:

import os, sys
from subprocess import Popen, PIPE
try:
    path = Popen("find / -name 'file' -type f", shell=True, stdout=PIPE).stdout.read().splitlines()[0]
    if not sys.path.__contains__(path):
        sys.path.append(path)
except IndexError:
    raise RuntimeError("You must have FILE to run this program!")

当然,除非您计划将它们打包在一起。但是,在这种情况下,您实际上并不需要两个单独的文件。

Call me overly cautious, but I like to make mine more portable because it’s unsafe to assume that files will always be in the same place on every computer. Personally I have the code look up the file path first. I use Linux so mine would look like this:

import os, sys
from subprocess import Popen, PIPE
try:
    path = Popen("find / -name 'file' -type f", shell=True, stdout=PIPE).stdout.read().splitlines()[0]
    if not sys.path.__contains__(path):
        sys.path.append(path)
except IndexError:
    raise RuntimeError("You must have FILE to run this program!")

That is of course unless you plan to package these together. But if that’s the case you don’t really need two separate files anyway.


即使使用__init__.py,也如何解决“尝试以非软件包方式进行相对导入”

问题:即使使用__init__.py,也如何解决“尝试以非软件包方式进行相对导入”

我正在尝试使用以下目录结构来遵循PEP 328

pkg/
  __init__.py
  components/
    core.py
    __init__.py
  tests/
    core_test.py
    __init__.py

core_test.py我有以下进口声明

from ..components.core import GameLoopEvents

但是,当我运行时,出现以下错误:

tests$ python core_test.py 
Traceback (most recent call last):
  File "core_test.py", line 3, in <module>
    from ..components.core import GameLoopEvents
ValueError: Attempted relative import in non-package

到处搜索时,我发现“ 即使使用__init__.py,相对路径也无法使用 ”和“ 从相对路径导入模块 ”,但是它们没有帮助。

我在这里想念什么吗?

I’m trying to follow PEP 328, with the following directory structure:

pkg/
  __init__.py
  components/
    core.py
    __init__.py
  tests/
    core_test.py
    __init__.py

In core_test.py I have the following import statement

from ..components.core import GameLoopEvents

However, when I run, I get the following error:

tests$ python core_test.py 
Traceback (most recent call last):
  File "core_test.py", line 3, in <module>
    from ..components.core import GameLoopEvents
ValueError: Attempted relative import in non-package

Searching around I found “relative path not working even with __init__.py” and “Import a module from a relative path” but they didn’t help.

Is there anything I’m missing here?


回答 0

是。您没有将其用作包装。

python -m pkg.tests.core_test

Yes. You’re not using it as a package.

python -m pkg.tests.core_test

回答 1

详细阐述伊格纳西奥·巴斯克斯·阿布拉姆斯答案:

Python导入机制相对于__name__当前文件起作用。直接执行文件时,它没有通常的名称,但是具有"__main__"以它的名称命名。因此,相对进口无效。

您可以按照Igancio的建议使用该-m选项执行它。如果包的一部分要作为脚本运行,则还可以使用__package__属性告诉该文件在包层次结构中应具有的名称。

参见http://www.python.org/dev/peps/pep-0366/详细信息,。

To elaborate on Ignacio Vazquez-Abrams’s answer:

The Python import mechanism works relative to the __name__ of the current file. When you execute a file directly, it doesn’t have its usual name, but has "__main__" as its name instead. So relative imports don’t work.

You can, as Igancio suggested, execute it using the -m option. If you have a part of your package that is meant to be run as a script, you can also use the __package__ attribute to tell that file what name it’s supposed to have in the package hierarchy.

See http://www.python.org/dev/peps/pep-0366/ for details.


回答 2

import components.core如果将当前目录附加到,则可以直接使用sys.path

if __name__ == '__main__' and __package__ is None:
    from os import sys, path
    sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))

You can use import components.core directly if you append the current directory to sys.path:

if __name__ == '__main__' and __package__ is None:
    from os import sys, path
    sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))

回答 3

这取决于您要如何启动脚本。

如果要以经典方式从命令行启动UnitTest,那就是:

python tests/core_test.py

然后,由于在这种情况下‘components’‘tests’是同级文件夹,因此您可以使用sys.path模块的insertappend方法导入相关模块。就像是:

import sys
from os import path
sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )
from components.core import GameLoopEvents

否则,您可以使用’-m’参数启动脚本(请注意,在这种情况下,我们正在谈论一个软件包,因此,您不能使用‘.py’扩展名),即:

python -m pkg.tests.core_test

在这种情况下,您可以像以前一样简单地使用相对导入:

from ..components.core import GameLoopEvents

最后,您可以将两种方法混合使用,以便您的脚本无论调用方式如何都可以正常工作。例如:

if __name__ == '__main__':
    if __package__ is None:
        import sys
        from os import path
        sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )
        from components.core import GameLoopEvents
    else:
        from ..components.core import GameLoopEvents

It depends on how you want to launch your script.

If you want to launch your UnitTest from the command line in a classic way, that is:

python tests/core_test.py

Then, since in this case ‘components’ and ‘tests’ are siblings folders, you can import the relative module either using the insert or the append method of the sys.path module. Something like:

import sys
from os import path
sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )
from components.core import GameLoopEvents

Otherwise, you can launch your script with the ‘-m’ argument (note that in this case, we are talking about a package, and thus you must not give the ‘.py’ extension), that is:

python -m pkg.tests.core_test

In such a case, you can simply use the relative import as you were doing:

from ..components.core import GameLoopEvents

You can finally mix the two approaches, so that your script will work no matter how it is called. For example:

if __name__ == '__main__':
    if __package__ is None:
        import sys
        from os import path
        sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )
        from components.core import GameLoopEvents
    else:
        from ..components.core import GameLoopEvents

回答 4

在core_test.py中,执行以下操作:

import sys
sys.path.append('../components')
from core import GameLoopEvents

In core_test.py, do the following:

import sys
sys.path.append('../components')
from core import GameLoopEvents

回答 5

如果您的用例是用于运行测试的,并且可以接缝,那么您可以执行以下操作。不要像python core_test.py使用那样运行测试框架来运行测试脚本pytest。然后在命令行上您可以输入

$$ py.test

这将在您的目录中运行测试。这得到周围人的问题__name__的存在__main__,是由@BrenBarn指出。接下来,将一个空__init__.py文件放入您的测试目录,这将使测试目录成为您程序包的一部分。那你就可以做

from ..components.core import GameLoopEvents

但是,如果您将测试脚本作为主程序运行,那么事情将再次失败。因此,只需使用测试运行器。也许这也适用于其他测试运行程序,例如,nosetests但我尚未检查。希望这可以帮助。

If your use case is for running tests, and it seams that it is, then you can do the following. Instead of running your test script as python core_test.py use a testing framework such as pytest. Then on the command line you can enter

$$ py.test

That will run the tests in your directory. This gets around the issue of __name__ being __main__ that was pointed out by @BrenBarn. Next, put an empty __init__.py file into your test directory, this will make the test directory part of your package. Then you will be able to do

from ..components.core import GameLoopEvents

However, if you run your test script as a main program then things will fail once again. So just use the test runner. Maybe this also works with other test runners such as nosetests but i haven’t checked it. Hope this helps.


回答 6

我的快速解决方案是将目录添加到路径:

import sys
sys.path.insert(0, '../components/')

My quick-fix is to add the directory to the path:

import sys
sys.path.insert(0, '../components/')

回答 7

问题在于您的测试方法,

你试过了 python core_test.py

那么您将收到此错误 ValueError:尝试在非包中进行相对导入

原因:您正在从非包装来源测试包装。

因此,请从软件包源测试模块。

如果这是您的项目结构,

pkg/
  __init__.py
  components/
    core.py
    __init__.py
  tests/
    core_test.py
    __init__.py

cd pkg

python -m tests.core_test # dont use .py

或从外部pkg /

python -m pkg.tests.core_test

.如果要从同一目录中的文件夹导入,则为Single 。每退一步,再增加一个。

hi/
  hello.py
how.py

how.py

from .hi import hello

如果你想从hello.py导入

from .. import how

Issue is with your testing method,

you tried python core_test.py

then you will get this error ValueError: Attempted relative import in non-package

Reason: you are testing your packaging from non-package source.

so test your module from package source.

if this is your project structure,

pkg/
  __init__.py
  components/
    core.py
    __init__.py
  tests/
    core_test.py
    __init__.py

cd pkg

python -m tests.core_test # dont use .py

or from outside pkg/

python -m pkg.tests.core_test

single . if you want to import from folder in same directory . for each step back add one more.

hi/
  hello.py
how.py

in how.py

from .hi import hello

incase if you want to import how from hello.py

from .. import how

回答 8

旧线程。我发现__all__= ['submodule', ...]__init__.py文件中添加,然后from <CURRENT_MODULE> import *在目标中使用可以正常工作。

Old thread. I found out that adding an __all__= ['submodule', ...] to the __init__.py file and then using the from <CURRENT_MODULE> import * in the target works fine.


回答 9

您可以使用from pkg.components.core import GameLoopEvents,例如我使用pycharm,下面是我的项目结构图像,我只是从根包中导入,然后就可以了:

在此处输入图片说明

You can use from pkg.components.core import GameLoopEvents, for example I use pycharm, the below is my project structure image, I just import from the root package, then it works:

enter image description here


回答 10

正如Paolo所说,我们有2种调用方法:

1) python -m tests.core_test
2) python tests/core_test.py

它们之间的区别是sys.path [0]字符串。由于解释将在导入时搜索sys.path,因此我们可以使用tests/core_test.py

if __name__ == '__main__':
    import sys
    from pathlib import Path
    sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
    from components import core
    <other stuff>

之后,我们可以使用其他方法运行core_test.py:

cd tests
python core_test.py
python -m core_test
...

注意,py36仅经过测试。

As Paolo said, we have 2 invocation methods:

1) python -m tests.core_test
2) python tests/core_test.py

One difference between them is sys.path[0] string. Since the interpret will search sys.path when doing import, we can do with tests/core_test.py:

if __name__ == '__main__':
    import sys
    from pathlib import Path
    sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
    from components import core
    <other stuff>

And more after this, we can run core_test.py with other methods:

cd tests
python core_test.py
python -m core_test
...

Note, py36 tested only.


回答 11

这种方法对我有用,并且比某些解决方案更混乱:

try:
  from ..components.core import GameLoopEvents
except ValueError:
  from components.core import GameLoopEvents

父目录位于我的PYTHONPATH中,并且__init__.py父目录和此目录中都有文件。

上面的代码始终在python 2中有效,但是python 3有时会遇到ImportError或ModuleNotFoundError(后者在python 3.6中是新功能,是ImportError的子类),因此以下调整对我在python 2和3中均有效:

try:
  from ..components.core import GameLoopEvents
except ( ValueError, ImportError):
  from components.core import GameLoopEvents

This approach worked for me and is less cluttered than some solutions:

try:
  from ..components.core import GameLoopEvents
except ValueError:
  from components.core import GameLoopEvents

The parent directory is in my PYTHONPATH, and there are __init__.py files in the parent directory and this directory.

The above always worked in python 2, but python 3 sometimes hit an ImportError or ModuleNotFoundError (the latter is new in python 3.6 and a subclass of ImportError), so the following tweak works for me in both python 2 and 3:

try:
  from ..components.core import GameLoopEvents
except ( ValueError, ImportError):
  from components.core import GameLoopEvents

回答 12

尝试这个

import components
from components import *

Try this

import components
from components import *

回答 13

如果有人正在寻找解决方法,我偶然发现了一个。这里有一些背景。我想测试文件中的一种方法。当我从内部运行时

if __name__ == "__main__":

它总是抱怨相对进口。我尝试应用上述解决方案,但由于许多嵌套文件,每个文件都有多个导入,因此无法正常工作。

这就是我所做的。我刚刚创建了一个启动器,一个外部程序,它将导入必要的方法并调用它们。虽然这不是一个很好的解决方案,但它可以工作。

If someone is looking for a workaround, I stumbled upon one. Here’s a bit of context. I wanted to test out one of the methods I’ve in a file. When I run it from within

if __name__ == "__main__":

it always complained of the relative imports. I tried to apply the above solutions, but failed to work, since there were many nested files, each with multiple imports.

Here’s what I did. I just created a launcher, an external program that would import necessary methods and call them. Though, not a great solution, it works.


回答 14

这是一种会惹恼所有人但效果很好的方法。在测试中运行:

ln -s ../components components

然后只需像往常一样导入组件。

Here’s one way which will piss off everyone but work pretty well. In tests run:

ln -s ../components components

Then just import components like you normally would.


回答 15

这非常令人困惑,如果您使用的是像pycharm这样的IDE,那就更令人困惑了。对我有用的方法:1.进行pycharm项目设置(如果从VE或python目录运行python)2.定义的方式没有错。有时它与from folder1.file1导入类一起使用

如果它不起作用,请使用import folder1.file1。3.您的环境变量应在系统中正确提及或在命令行参数中提供。

This is very confusing, and if you are using IDE like pycharm, it’s little more confusing. What worked for me: 1. Make pycharm project settings (if you are running python from a VE or from python directory) 2. There is no wrong the way you defined. sometime it works with from folder1.file1 import class

if it does not work, use import folder1.file1 3. Your environment variable should be correctly mentioned in system or provide it in your command line argument.


回答 16

由于您的代码包含if __name__ == "__main__",而不会作为包导入,因此最好使用它sys.path.append()来解决问题。

Because your code contains if __name__ == "__main__", which doesn’t be imported as a package, you’d better use sys.path.append() to solve the problem.


Python 3中的相对导入

问题:Python 3中的相对导入

我想从同一目录中的另一个文件导入函数。

有时它对我有用,from .mymodule import myfunction但有时我得到:

SystemError: Parent module '' not loaded, cannot perform relative import

有时它可与一起使用from mymodule import myfunction,但有时我也会得到:

SystemError: Parent module '' not loaded, cannot perform relative import

我不了解这里的逻辑,也找不到任何解释。这看起来完全是随机的。

有人可以向我解释所有这些背后的逻辑是什么?

I want to import a function from another file in the same directory.

Sometimes it works for me with from .mymodule import myfunction but sometimes I get a:

SystemError: Parent module '' not loaded, cannot perform relative import

Sometimes it works with from mymodule import myfunction, but sometimes I also get a:

SystemError: Parent module '' not loaded, cannot perform relative import

I don’t understand the logic here, and I couldn’t find any explanation. This looks completely random.

Could someone explain to me what’s the logic behind all this?


回答 0

不幸的是,该模块需要位于程序包内部,有时还需要作为脚本运行。知道如何实现吗?

像这样的布局很普遍…

main.py
mypackage/
    __init__.py
    mymodule.py
    myothermodule.py

mymodule.py像这样…

#!/usr/bin/env python3

# Exported function
def as_int(a):
    return int(a)

# Test function for module  
def _test():
    assert as_int('1') == 1

if __name__ == '__main__':
    _test()

……一个myothermodule.py像这样…

#!/usr/bin/env python3

from .mymodule import as_int

# Exported function
def add(a, b):
    return as_int(a) + as_int(b)

# Test function for module  
def _test():
    assert add('1', '1') == 2

if __name__ == '__main__':
    _test()

main.py这样的…

#!/usr/bin/env python3

from mypackage.myothermodule import add

def main():
    print(add('1', '1'))

if __name__ == '__main__':
    main()

…在您运行main.py或时工作正常mypackage/mymodule.py,但mypackage/myothermodule.py由于相对导入而失败,…

from .mymodule import as_int

您应该运行它的方式是…

python3 -m mypackage.myothermodule

…但是有些冗长,并且与像这样的shebang行不能很好地融合在一起#!/usr/bin/env python3

假设名称mymodule在全球范围内是唯一的,这种情况下最简单的解决方法是避免使用相对导入,而只需使用…

from mymodule import as_int

…尽管它不是唯一的,或者您的包结构更复杂,您仍需要在中包含包含包目录的目录PYTHONPATH,并按以下步骤进行操作…

from mypackage.mymodule import as_int

…或者如果您希望它“开箱即用”运行,则可以PYTHONPATH使用此方法首先获取输入代码…

import sys
import os

PACKAGE_PARENT = '..'
SCRIPT_DIR = os.path.dirname(os.path.realpath(os.path.join(os.getcwd(), os.path.expanduser(__file__))))
sys.path.append(os.path.normpath(os.path.join(SCRIPT_DIR, PACKAGE_PARENT)))

from mypackage.mymodule import as_int

这有点痛苦,但是有一个线索可以说明为什么某位Guido van Rossum写的电子邮件中

我对此表示怀疑,也对任何其他提议的__main__ 机械装置都为-1 。唯一的用例似乎是正在运行的脚本,它们恰好位于模块目录中,我一直将其视为反模式。为了让我改变主意,您必须说服我不要。

在程序包中运行脚本是否是反模式是主观的,但是就我个人而言,我发现它在包含一些自定义wxPython小部件的程序包中非常有用,因此我可以为任何源文件运行脚本以wx.Frame仅显示包含该小部件用于测试目的。

unfortunately, this module needs to be inside the package, and it also needs to be runnable as a script, sometimes. Any idea how I could achieve that?

It’s quite common to have a layout like this…

main.py
mypackage/
    __init__.py
    mymodule.py
    myothermodule.py

…with a mymodule.py like this…

#!/usr/bin/env python3

# Exported function
def as_int(a):
    return int(a)

# Test function for module  
def _test():
    assert as_int('1') == 1

if __name__ == '__main__':
    _test()

…a myothermodule.py like this…

#!/usr/bin/env python3

from .mymodule import as_int

# Exported function
def add(a, b):
    return as_int(a) + as_int(b)

# Test function for module  
def _test():
    assert add('1', '1') == 2

if __name__ == '__main__':
    _test()

…and a main.py like this…

#!/usr/bin/env python3

from mypackage.myothermodule import add

def main():
    print(add('1', '1'))

if __name__ == '__main__':
    main()

…which works fine when you run main.py or mypackage/mymodule.py, but fails with mypackage/myothermodule.py, due to the relative import…

from .mymodule import as_int

The way you’re supposed to run it is…

python3 -m mypackage.myothermodule

…but it’s somewhat verbose, and doesn’t mix well with a shebang line like #!/usr/bin/env python3.

The simplest fix for this case, assuming the name mymodule is globally unique, would be to avoid using relative imports, and just use…

from mymodule import as_int

…although, if it’s not unique, or your package structure is more complex, you’ll need to include the directory containing your package directory in PYTHONPATH, and do it like this…

from mypackage.mymodule import as_int

…or if you want it to work “out of the box”, you can frob the PYTHONPATH in code first with this…

import sys
import os

PACKAGE_PARENT = '..'
SCRIPT_DIR = os.path.dirname(os.path.realpath(os.path.join(os.getcwd(), os.path.expanduser(__file__))))
sys.path.append(os.path.normpath(os.path.join(SCRIPT_DIR, PACKAGE_PARENT)))

from mypackage.mymodule import as_int

It’s kind of a pain, but there’s a clue as to why in an email written by a certain Guido van Rossum…

I’m -1 on this and on any other proposed twiddlings of the __main__ machinery. The only use case seems to be running scripts that happen to be living inside a module’s directory, which I’ve always seen as an antipattern. To make me change my mind you’d have to convince me that it isn’t.

Whether running scripts inside a package is an antipattern or not is subjective, but personally I find it really useful in a package I have which contains some custom wxPython widgets, so I can run the script for any of the source files to display a wx.Frame containing only that widget for testing purposes.


回答 1

说明

PEP 328

相对导入使用模块的__name__属性来确定该模块在包层次结构中的位置。如果模块的名称不包含任何包信息(例如,将其设置为’__main__’), 则相对导入的解析就好像该模块是顶级模块一样,无论该模块实际位于文件系统上的哪个位置。

在某些时候,PEP 338PEP 328冲突:

…相对导入依赖于__name__来确定当前模块在包层次结构中的位置。在主模块中,__name__的值始终为‘__main__’,因此显式相对导入将始终失败(因为它们仅适用于包中的模块)

为了解决这个问题,PEP 366引入了顶层变量__package__

通过添加新的模块级别属性,如果使用-m 开关执行模块,则该PEP允许相对导入自动进行。当按名称执行文件时,模块本身中的少量样板文件将允许相对导入工作。[…]如果存在[属性],则相对导入将基于此属性而不是模块__name__属性。[…]当通过其文件名指定主模块时,__package__属性将设置为None。[…] 当导入系统在未设置__package__的模块(或将其设置为None)的模块中遇到显式相对导入时,它将计算并存储正确的值__name __。rpartition(’。’)[0]用于常规模块__ name__用于程序包初始化模块)

(强调我的)

如果__name__'__main__',则__name__.rpartition('.')[0]返回空字符串。这就是为什么错误描述中有空字符串文字的原因:

SystemError: Parent module '' not loaded, cannot perform relative import

CPython PyImport_ImportModuleLevelObject函数的相关部分:

if (PyDict_GetItem(interp->modules, package) == NULL) {
    PyErr_Format(PyExc_SystemError,
            "Parent module %R not loaded, cannot perform relative "
            "import", package);
    goto error;
}

如果CPython packageinterp->modules(可通过访问)中找不到(包的名称),则会引发此异常sys.modules。由于sys.modules“将模块名称映射到已经加载的模块的字典”,因此现在很清楚,必须在执行相对导入之前显式绝对导入父模块

注意:问题18018中 的补丁添加了另一个ifblock,它将在以上代码之前执行:

if (PyUnicode_CompareWithASCIIString(package, "") == 0) {
    PyErr_SetString(PyExc_ImportError,
            "attempted relative import with no known parent package");
    goto error;
} /* else if (PyDict_GetItem(interp->modules, package) == NULL) {
    ...
*/

如果package(与上面相同)为空字符串,则错误消息将为

ImportError: attempted relative import with no known parent package

但是,您只会在Python 3.6或更高版本中看到它。

解决方案1:使用-m运行脚本

考虑一个目录(这是一个Python ):

.
├── package
│   ├── __init__.py
│   ├── module.py
│   └── standalone.py

软件包中的所有文件均以相同的两行代码开头:

from pathlib import Path
print('Running' if __name__ == '__main__' else 'Importing', Path(__file__).resolve())

我加入这两行只是为了使操作顺序显而易见。我们可以完全忽略它们,因为它们不会影响执行。

__init__.pymodule.py仅包含这两行(即,它们实际上是空的)。

standalone.py另外尝试通过相对导入来导入module.py

from . import module  # explicit relative import

我们深知这/path/to/python/interpreter package/standalone.py将失败。但是,我们可以使用-m命令行选项运行该模块,该选项“搜索sys.path命名的模块并将其内容作为__main__模块执行”

vaultah@base:~$ python3 -i -m package.standalone
Importing /home/vaultah/package/__init__.py
Running /home/vaultah/package/standalone.py
Importing /home/vaultah/package/module.py
>>> __file__
'/home/vaultah/package/standalone.py'
>>> __package__
'package'
>>> # The __package__ has been correctly set and module.py has been imported.
... # What's inside sys.modules?
... import sys
>>> sys.modules['__main__']
<module 'package.standalone' from '/home/vaultah/package/standalone.py'>
>>> sys.modules['package.module']
<module 'package.module' from '/home/vaultah/package/module.py'>
>>> sys.modules['package']
<module 'package' from '/home/vaultah/package/__init__.py'>

-m为您完成所有导入工作并自动设置__package__,但是您可以在

解决方案2:手动设置__package__

请把它当作概念证明而不是实际解决方案。它不适合在实际代码中使用。

PEP 366可以解决此问题,但是它不完整,因为__package__仅设置是不够的。您将需要至少在模块层次结构中导入N个先前的软件包,其中N是要搜索要导入的模块的父目录(相对于脚本目录)的数量。

从而,

  1. 将当前模块的第N个前辈的父目录添加到sys.path

  2. 从中删除当前文件的目录 sys.path

  3. 使用标准名称导入当前模块的父模块

  4. 设置__package__2的标准名称

  5. 执行相对导入

我将从解决方案1中借用文件,并添加更多子包:

package
├── __init__.py
├── module.py
└── subpackage
    ├── __init__.py
    └── subsubpackage
        ├── __init__.py
        └── standalone.py

这次standalone.py将使用以下相对导入方式从软件包中导入module.py

from ... import module  # N = 3

我们需要在该行之前加上样板代码,以使其正常工作。

import sys
from pathlib import Path

if __name__ == '__main__' and __package__ is None:
    file = Path(__file__).resolve()
    parent, top = file.parent, file.parents[3]

    sys.path.append(str(top))
    try:
        sys.path.remove(str(parent))
    except ValueError: # Already removed
        pass

    import package.subpackage.subsubpackage
    __package__ = 'package.subpackage.subsubpackage'

from ... import module # N = 3

它允许我们按文件名执行standalone.py

vaultah@base:~$ python3 package/subpackage/subsubpackage/standalone.py
Running /home/vaultah/package/subpackage/subsubpackage/standalone.py
Importing /home/vaultah/package/__init__.py
Importing /home/vaultah/package/subpackage/__init__.py
Importing /home/vaultah/package/subpackage/subsubpackage/__init__.py
Importing /home/vaultah/package/module.py

包裹在一个功能更通用的解决方案,可以发现在这里。用法示例:

if __name__ == '__main__' and __package__ is None:
    import_parents(level=3) # N = 3

from ... import module
from ...module.submodule import thing

解决方案3:使用绝对导入和设置工具

步骤是-

  1. 将显式相对导入替换为等效的绝对导入

  2. 安装package以使其可导入

例如,目录结构可以如下

.
├── project
│   ├── package
│   │   ├── __init__.py
│   │   ├── module.py
│   │   └── standalone.py
│   └── setup.py

其中setup.py

from setuptools import setup, find_packages
setup(
    name = 'your_package_name',
    packages = find_packages(),
)

其余文件是从解决方案#1借用的。

安装后,无论您的工作目录如何,都可以导入软件包(假设没有命名问题)。

我们可以修改standalone.py以利用这一优势(步骤1):

from package import module  # absolute import

将工作目录更改为project并运行/path/to/python/interpreter setup.py install --user--user将软件包安装在site-packages目录中)(步骤2):

vaultah@base:~$ cd project
vaultah@base:~/project$ python3 setup.py install --user

让我们验证一下现在可以将standalone.py作为脚本运行:

vaultah@base:~/project$ python3 -i package/standalone.py
Running /home/vaultah/project/package/standalone.py
Importing /home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/__init__.py
Importing /home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/module.py
>>> module
<module 'package.module' from '/home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/module.py'>
>>> import sys
>>> sys.modules['package']
<module 'package' from '/home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/__init__.py'>
>>> sys.modules['package.module']
<module 'package.module' from '/home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/module.py'>

注意:如果您决定走这条路,最好使用虚拟环境来隔离安装软件包。

解决方案4:使用绝对导入和一些样板代码

坦白地说,不需要安装-您可以在脚本中添加一些样板代码以使绝对导入工作。

我将从解决方案1借用文件并更改standalone.py

  1. 尝试使用绝对导入从包中导入任何内容之前,将的父目录添加到:sys.path

    import sys
    from pathlib import Path # if you haven't already done so
    file = Path(__file__).resolve()
    parent, root = file.parent, file.parents[1]
    sys.path.append(str(root))
    
    # Additionally remove the current file's directory from sys.path
    try:
        sys.path.remove(str(parent))
    except ValueError: # Already removed
        pass
  2. 用绝对导入替换相对导入:

    from package import module  # absolute import

standalone.py运行没有问题:

vaultah@base:~$ python3 -i package/standalone.py
Running /home/vaultah/package/standalone.py
Importing /home/vaultah/package/__init__.py
Importing /home/vaultah/package/module.py
>>> module
<module 'package.module' from '/home/vaultah/package/module.py'>
>>> import sys
>>> sys.modules['package']
<module 'package' from '/home/vaultah/package/__init__.py'>
>>> sys.modules['package.module']
<module 'package.module' from '/home/vaultah/package/module.py'>

我认为我应该警告您:请不要这样做,尤其是在您的项目结构复杂的情况下。


作为附带说明,PEP 8建议使用绝对导入,但指出在某些情况下,显式相对导入是可以接受的:

建议使用绝对导入,因为它们通常更具可读性,并且往往表现得更好(或至少会提供更好的错误消息)。[…]但是,显式相对导入是绝对导入的一种可接受的替代方法,尤其是在处理复杂的包装布局时,使用绝对导入会不必要地冗长。

Explanation

From PEP 328

Relative imports use a module’s __name__ attribute to determine that module’s position in the package hierarchy. If the module’s name does not contain any package information (e.g. it is set to ‘__main__’) then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.

At some point PEP 338 conflicted with PEP 328:

… relative imports rely on __name__ to determine the current module’s position in the package hierarchy. In a main module, the value of __name__ is always ‘__main__’, so explicit relative imports will always fail (as they only work for a module inside a package)

and to address the issue, PEP 366 introduced the top level variable __package__:

By adding a new module level attribute, this PEP allows relative imports to work automatically if the module is executed using the -m switch. A small amount of boilerplate in the module itself will allow the relative imports to work when the file is executed by name. […] When it [the attribute] is present, relative imports will be based on this attribute rather than the module __name__ attribute. […] When the main module is specified by its filename, then the __package__ attribute will be set to None. […] When the import system encounters an explicit relative import in a module without __package__ set (or with it set to None), it will calculate and store the correct value (__name__.rpartition(‘.’)[0] for normal modules and __name__ for package initialisation modules)

(emphasis mine)

If the __name__ is '__main__', __name__.rpartition('.')[0] returns empty string. This is why there’s empty string literal in the error description:

SystemError: Parent module '' not loaded, cannot perform relative import

The relevant part of the CPython’s PyImport_ImportModuleLevelObject function:

if (PyDict_GetItem(interp->modules, package) == NULL) {
    PyErr_Format(PyExc_SystemError,
            "Parent module %R not loaded, cannot perform relative "
            "import", package);
    goto error;
}

CPython raises this exception if it was unable to find package (the name of the package) in interp->modules (accessible as sys.modules). Since sys.modules is “a dictionary that maps module names to modules which have already been loaded”, it’s now clear that the parent module must be explicitly absolute-imported before performing relative import.

Note: The patch from the issue 18018 has added another if block, which will be executed before the code above:

if (PyUnicode_CompareWithASCIIString(package, "") == 0) {
    PyErr_SetString(PyExc_ImportError,
            "attempted relative import with no known parent package");
    goto error;
} /* else if (PyDict_GetItem(interp->modules, package) == NULL) {
    ...
*/

If package (same as above) is empty string, the error message will be

ImportError: attempted relative import with no known parent package

However, you will only see this in Python 3.6 or newer.

Solution #1: Run your script using -m

Consider a directory (which is a Python package):

.
├── package
│   ├── __init__.py
│   ├── module.py
│   └── standalone.py

All of the files in package begin with the same 2 lines of code:

from pathlib import Path
print('Running' if __name__ == '__main__' else 'Importing', Path(__file__).resolve())

I’m including these two lines only to make the order of operations obvious. We can ignore them completely, since they don’t affect the execution.

__init__.py and module.py contain only those two lines (i.e., they are effectively empty).

standalone.py additionally attempts to import module.py via relative import:

from . import module  # explicit relative import

We’re well aware that /path/to/python/interpreter package/standalone.py will fail. However, we can run the module with the -m command line option that will “search sys.path for the named module and execute its contents as the __main__ module”:

vaultah@base:~$ python3 -i -m package.standalone
Importing /home/vaultah/package/__init__.py
Running /home/vaultah/package/standalone.py
Importing /home/vaultah/package/module.py
>>> __file__
'/home/vaultah/package/standalone.py'
>>> __package__
'package'
>>> # The __package__ has been correctly set and module.py has been imported.
... # What's inside sys.modules?
... import sys
>>> sys.modules['__main__']
<module 'package.standalone' from '/home/vaultah/package/standalone.py'>
>>> sys.modules['package.module']
<module 'package.module' from '/home/vaultah/package/module.py'>
>>> sys.modules['package']
<module 'package' from '/home/vaultah/package/__init__.py'>

-m does all the importing stuff for you and automatically sets __package__, but you can do that yourself in the

Solution #2: Set __package__ manually

Please treat it as a proof of concept rather than an actual solution. It isn’t well-suited for use in real-world code.

PEP 366 has a workaround to this problem, however, it’s incomplete, because setting __package__ alone is not enough. You’re going to need to import at least N preceding packages in the module hierarchy, where N is the number of parent directories (relative to the directory of the script) that will be searched for the module being imported.

Thus,

  1. Add the parent directory of the Nth predecessor of the current module to sys.path

  2. Remove the current file’s directory from sys.path

  3. Import the parent module of the current module using its fully-qualified name

  4. Set __package__ to the fully-qualified name from 2

  5. Perform the relative import

I’ll borrow files from the Solution #1 and add some more subpackages:

package
├── __init__.py
├── module.py
└── subpackage
    ├── __init__.py
    └── subsubpackage
        ├── __init__.py
        └── standalone.py

This time standalone.py will import module.py from the package package using the following relative import

from ... import module  # N = 3

We’ll need to precede that line with the boilerplate code, to make it work.

import sys
from pathlib import Path

if __name__ == '__main__' and __package__ is None:
    file = Path(__file__).resolve()
    parent, top = file.parent, file.parents[3]

    sys.path.append(str(top))
    try:
        sys.path.remove(str(parent))
    except ValueError: # Already removed
        pass

    import package.subpackage.subsubpackage
    __package__ = 'package.subpackage.subsubpackage'

from ... import module # N = 3

It allows us to execute standalone.py by filename:

vaultah@base:~$ python3 package/subpackage/subsubpackage/standalone.py
Running /home/vaultah/package/subpackage/subsubpackage/standalone.py
Importing /home/vaultah/package/__init__.py
Importing /home/vaultah/package/subpackage/__init__.py
Importing /home/vaultah/package/subpackage/subsubpackage/__init__.py
Importing /home/vaultah/package/module.py

A more general solution wrapped in a function can be found here. Example usage:

if __name__ == '__main__' and __package__ is None:
    import_parents(level=3) # N = 3

from ... import module
from ...module.submodule import thing

Solution #3: Use absolute imports and setuptools

The steps are –

  1. Replace explicit relative imports with equivalent absolute imports

  2. Install package to make it importable

For instance, the directory structure may be as follows

.
├── project
│   ├── package
│   │   ├── __init__.py
│   │   ├── module.py
│   │   └── standalone.py
│   └── setup.py

where setup.py is

from setuptools import setup, find_packages
setup(
    name = 'your_package_name',
    packages = find_packages(),
)

The rest of the files were borrowed from the Solution #1.

Installation will allow you to import the package regardless of your working directory (assuming there’ll be no naming issues).

We can modify standalone.py to use this advantage (step 1):

from package import module  # absolute import

Change your working directory to project and run /path/to/python/interpreter setup.py install --user (--user installs the package in your site-packages directory) (step 2):

vaultah@base:~$ cd project
vaultah@base:~/project$ python3 setup.py install --user

Let’s verify that it’s now possible to run standalone.py as a script:

vaultah@base:~/project$ python3 -i package/standalone.py
Running /home/vaultah/project/package/standalone.py
Importing /home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/__init__.py
Importing /home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/module.py
>>> module
<module 'package.module' from '/home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/module.py'>
>>> import sys
>>> sys.modules['package']
<module 'package' from '/home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/__init__.py'>
>>> sys.modules['package.module']
<module 'package.module' from '/home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/module.py'>

Note: If you decide to go down this route, you’d be better off using virtual environments to install packages in isolation.

Solution #4: Use absolute imports and some boilerplate code

Frankly, the installation is not necessary – you could add some boilerplate code to your script to make absolute imports work.

I’m going to borrow files from Solution #1 and change standalone.py:

  1. Add the parent directory of package to sys.path before attempting to import anything from package using absolute imports:

    import sys
    from pathlib import Path # if you haven't already done so
    file = Path(__file__).resolve()
    parent, root = file.parent, file.parents[1]
    sys.path.append(str(root))
    
    # Additionally remove the current file's directory from sys.path
    try:
        sys.path.remove(str(parent))
    except ValueError: # Already removed
        pass
    
  2. Replace the relative import by the absolute import:

    from package import module  # absolute import
    

standalone.py runs without problems:

vaultah@base:~$ python3 -i package/standalone.py
Running /home/vaultah/package/standalone.py
Importing /home/vaultah/package/__init__.py
Importing /home/vaultah/package/module.py
>>> module
<module 'package.module' from '/home/vaultah/package/module.py'>
>>> import sys
>>> sys.modules['package']
<module 'package' from '/home/vaultah/package/__init__.py'>
>>> sys.modules['package.module']
<module 'package.module' from '/home/vaultah/package/module.py'>

I feel that I should warn you: try not to do this, especially if your project has a complex structure.


As a side note, PEP 8 recommends the use of absolute imports, but states that in some scenarios explicit relative imports are acceptable:

Absolute imports are recommended, as they are usually more readable and tend to be better behaved (or at least give better error messages). […] However, explicit relative imports are an acceptable alternative to absolute imports, especially when dealing with complex package layouts where using absolute imports would be unnecessarily verbose.


回答 2

将其放入包的__init__.py文件中

# For relative imports to work in Python 3.6
import os, sys; sys.path.append(os.path.dirname(os.path.realpath(__file__)))

假设您的包裹是这样的:

├── project
   ├── package
      ├── __init__.py
      ├── module1.py
      └── module2.py
   └── setup.py

现在在包中使用常规导入,例如:

# in module2.py
from module1 import class1

这适用于python 2和3。

Put this inside your package’s __init__.py file:

# For relative imports to work in Python 3.6
import os, sys; sys.path.append(os.path.dirname(os.path.realpath(__file__)))

Assuming your package is like this:

├── project
│   ├── package
│   │   ├── __init__.py
│   │   ├── module1.py
│   │   └── module2.py
│   └── setup.py

Now use regular imports in you package, like:

# in module2.py
from module1 import class1

This works in both python 2 and 3.


回答 3

我遇到了这个问题。黑客的解决方法是通过if / else块导入,如下所示:

#!/usr/bin/env python3
#myothermodule

if __name__ == '__main__':
    from mymodule import as_int
else:
    from .mymodule import as_int


# Exported function
def add(a, b):
    return as_int(a) + as_int(b)

# Test function for module  
def _test():
    assert add('1', '1') == 2

if __name__ == '__main__':
    _test()

I ran into this issue. A hack workaround is importing via an if/else block like follows:

#!/usr/bin/env python3
#myothermodule

if __name__ == '__main__':
    from mymodule import as_int
else:
    from .mymodule import as_int


# Exported function
def add(a, b):
    return as_int(a) + as_int(b)

# Test function for module  
def _test():
    assert add('1', '1') == 2

if __name__ == '__main__':
    _test()

回答 4

希望这对那里的某人有价值-我浏览了六堆stackoverflow帖子,试图找出与上面上面发布的内容类似的相对进口量。我按照建议设置了所有内容,但仍在执行ModuleNotFoundError: No module named 'my_module_name'

由于我只是在本地开发和玩耍,所以我没有创建/运行setup.py文件。我也没有明显地设置了我PYTHONPATH

我意识到,当我像在模块位于同一目录中那样运行代码时,找不到模块:

$ python3 test/my_module/module_test.py                                                                                                               2.4.0
Traceback (most recent call last):
  File "test/my_module/module_test.py", line 6, in <module>
    from my_module.module import *
ModuleNotFoundError: No module named 'my_module'

但是,当我明确指定路径时,事情开始起作用:

$ PYTHONPATH=. python3 test/my_module/module_test.py                                                                                                  2.4.0
...........
----------------------------------------------------------------------
Ran 11 tests in 0.001s

OK

因此,如果有人尝试了一些建议,则认为他们的代码结构正确,并且如果您不将当前目录导出到PYTHONPATH,则仍然遇到与我类似的情况:

  1. 运行您的代码,并明确包含如下路径: $ PYTHONPATH=. python3 test/my_module/module_test.py
  2. 为避免调用PYTHONPATH=.,请创建一个setup.py内容如下的文件,然后运行python setup.py development以将软件包添加到路径中:
# setup.py
from setuptools import setup, find_packages

setup(
    name='sample',
    packages=find_packages()
)

Hopefully, this will be of value to someone out there – I went through half a dozen stackoverflow posts trying to figure out relative imports similar to whats posted above here. I set up everything as suggested but I was still hitting ModuleNotFoundError: No module named 'my_module_name'

Since I was just developing locally and playing around, I hadn’t created/run a setup.py file. I also hadn’t apparently set my PYTHONPATH.

I realized that when I ran my code as I had been when the tests were in the same directory as the module, I couldn’t find my module:

$ python3 test/my_module/module_test.py                                                                                                               2.4.0
Traceback (most recent call last):
  File "test/my_module/module_test.py", line 6, in <module>
    from my_module.module import *
ModuleNotFoundError: No module named 'my_module'

However, when I explicitly specified the path things started to work:

$ PYTHONPATH=. python3 test/my_module/module_test.py                                                                                                  2.4.0
...........
----------------------------------------------------------------------
Ran 11 tests in 0.001s

OK

So, in the event that anyone has tried a few suggestions, believes their code is structured correctly and still finds themselves in a similar situation as myself try either of the following if you don’t export the current directory to your PYTHONPATH:

  1. Run your code and explicitly include the path like so: $ PYTHONPATH=. python3 test/my_module/module_test.py
  2. To avoid calling PYTHONPATH=., create a setup.py file with contents like the following and run python setup.py development to add packages to the path:
# setup.py
from setuptools import setup, find_packages

setup(
    name='sample',
    packages=find_packages()
)

回答 5

我需要从主项目目录运行python3才能使其工作。

例如,如果项目具有以下结构:

project_demo/
├── main.py
├── some_package/
   ├── __init__.py
   └── project_configs.py
└── test/
    └── test_project_configs.py

我将在文件夹project_demo /中运行python3 ,然后执行

from some_package import project_configs

I needed to run python3 from the main project directory to make it work.

For example, if the project has the following structure:

project_demo/
├── main.py
├── some_package/
│   ├── __init__.py
│   └── project_configs.py
└── test/
    └── test_project_configs.py

Solution

I would run python3 inside folder project_demo/ and then perform a

from some_package import project_configs

回答 6

为了解决这个问题,我设计了带有重新包装软件包的解决方案,该解决方案已经为我服务了一段时间。它将上层目录添加到lib路径:

import repackage
repackage.up()
from mypackage.mymodule import myfunction

重新打包可以使用智能策略(检查调用堆栈)进行相对导入,从而在各种情况下都起作用。

To obviate this problem, I devised a solution with the repackage package, which has worked for me for some time. It adds the upper directory to the lib path:

import repackage
repackage.up()
from mypackage.mymodule import myfunction

Repackage can make relative imports that work in a wide range of cases, using an intelligent strategy (inspecting the call stack).


回答 7

如果两个软件包都在您的导入路径(sys.path)中,并且您想要的模块/类在example / example.py中,则在没有相对导入的情况下访问该类,请尝试:

from example.example import fkt

if both packages are in your import path (sys.path), and the module/class you want is in example/example.py, then to access the class without relative import try:

from example.example import fkt

回答 8

我认为最好的解决方案是为您的模块创建一个软件包: 是有关如何执行操作的更多信息。

有了软件包后,您就不必担心相对导入了,就可以进行绝对导入。

I think the best solution is to create a package for your module: Here is more info on how to do it.

Once you have a package you don’t need to worry about relative import, you can just do absolute imports.


回答 9

我有一个类似的问题:我需要一个Linux服务和cgi插件,它们使用公共常量进行协作。做到这一点的“自然”方法是将它们放在程序包的init .py中,但是我无法使用-m参数启动cgi插件。

我的最终解决方案与上述解决方案2类似:

import sys
import pathlib as p
import importlib

pp = p.Path(sys.argv[0])
pack = pp.resolve().parent

pkg = importlib.import_module('__init__', package=str(pack))

缺点是必须在常量(或通用函数)前加上pkg:

print(pkg.Glob)

I had a similar problem: I needed a Linux service and cgi plugin which use common constants to cooperate. The ‘natural’ way to do this is to place them in the init.py of the package, but I cannot start the cgi plugin with the -m parameter.

My final solution was similar to Solution #2 above:

import sys
import pathlib as p
import importlib

pp = p.Path(sys.argv[0])
pack = pp.resolve().parent

pkg = importlib.import_module('__init__', package=str(pack))

The disadvantage is that you must prefix the constants (or common functions) with pkg:

print(pkg.Glob)