标签归档:python-module

ImportError:libSM.so.6:无法打开共享库文件:没有这样的文件或目录

问题:ImportError:libSM.so.6:无法打开共享库文件:没有这样的文件或目录

尝试导入OpenCV时,使用import cv2我得到以下错误:

/usr/local/lib/python2.7/dist-packages/cv2/__init__.py in <module>()
      7 
      8 # make IDE's (PyCharm) autocompletion happy
----> 9 from .cv2 import *
     10 
     11 # wildcard import above does not import "private" variables like __version__

ImportError: libSM.so.6: cannot open shared object file: No such file or directory

不确定如何解决-尝试使用Google的新协作工具。笔记本在这里:https : //drive.google.com/file/d/0B7-sJqBiyjCcRmFkMzl6cy1iN0k/view?usp=sharing

When trying to import OpenCV, using import cv2 I get the following error:

/usr/local/lib/python2.7/dist-packages/cv2/__init__.py in <module>()
      7 
      8 # make IDE's (PyCharm) autocompletion happy
----> 9 from .cv2 import *
     10 
     11 # wildcard import above does not import "private" variables like __version__

ImportError: libSM.so.6: cannot open shared object file: No such file or directory

Not sure how to fix this – trying to play around with Google’s new Colaboratory tool. Notebook is here: https://drive.google.com/file/d/0B7-sJqBiyjCcRmFkMzl6cy1iN0k/view?usp=sharing


回答 0

通过将其作为脚本的前两行来解决此问题:

!pip install opencv-python
!apt update && apt install -y libsm6 libxext6
!apt-get install -y libxrender-dev

This fixed the problem by having it as the first two lines of the script:

!pip install opencv-python
!apt update && apt install -y libsm6 libxext6
!apt-get install -y libxrender-dev

回答 1

您需要添加sudo。我做了以下事情来安装它:

sudo apt-get install libsm6 libxrender1 libfontconfig1

然后这样做(可选!也许您将不需要它)

sudo python3 -m pip install opencv-contrib-python

终于完成了!

You need to add sudo . I did the following to get it installed :

sudo apt-get install libsm6 libxrender1 libfontconfig1

and then did that (optional! maybe you won’t need it)

sudo python3 -m pip install opencv-contrib-python

FINALLY got it done !


回答 2

对于CentOS,运行以下命令: sudo yum install libXext libSM libXrender

For CentOS, run this: sudo yum install libXext libSM libXrender


回答 3

现在有一个无头版本,opencv-python该版本删除了图形依赖性(如libSM)。您可以在发布页面上看到普通版/无头版(以及导致该问题GitHub问题);只需-headless在安装时添加,例如

pip install opencv-python-headless
# also contrib, if needed
pip install opencv-contrib-python-headless

There is now a headless version of opencv-python which removes the graphical dependencies (like libSM). You can see the normal / headless version on the releases page (and the GitHub issue leading to this); just add -headless when installing, e.g.,

pip install opencv-python-headless
# also contrib, if needed
pip install opencv-contrib-python-headless

回答 4

可能是您的问题 python-opencv版本。最好将您的版本降级到3.3.0.9,其中不包含任何GUI依赖项。在GitHub的此处找到了相同的问题的答案链接。

May be the problem is with your python-opencv version. It’s better to downgrade your version to 3.3.0.9 which does not include any GUI dependencies. Same question was found on GitHub here the link to the answer.


回答 5

我在python:3.7-slimdocker盒上遇到了openCV的类似问题。以下对我有用:

apt-get install build-essential libglib2.0-0 libsm6 libxext6 libxrender-dev

请查看是否有帮助!

I was facing similar issue with openCV on the python:3.7-slim docker box. Following did the trick for me :

apt-get install build-essential libglib2.0-0 libsm6 libxext6 libxrender-dev

Please see if this helps !


回答 6

我无法在Google Cloud Platform的Ubuntu上运行的Anaconda-Jupyter笔记本上安装cv2。但是我找到了一种方法,如下所示:

从ssh终端运行以下命令,并按照说明进行操作:

 sudo apt-get install libsm6 libxrender1 libfontconfig1

安装完毕后,打开Jupyter笔记本并运行以下命令:

!pip install opencv-contrib-python

注意:我尝试运行此命令:“ sudo python3 -m pip install opencv-contrib-python”,但显示错误。但是以上命令对我有用。

现在刷新笔记本页面,并通过import cv2在笔记本中运行检查它是否已安装。

I was not able to install cv2 on Anaconda-Jupyter notebook running on Ubuntu on Google Cloud Platform. But I found a way to do it as follows:

Run the following command from the ssh terminal and follow the instruction:

 sudo apt-get install libsm6 libxrender1 libfontconfig1

Once its installed Open the Jupyter notebook and run following command:

!pip install opencv-contrib-python

Note: I tried to run this command: “sudo python3 -m pip install opencv-contrib-python”but it was showing an error. But above command worked for me.

Now refresh the notebook page and check whether it’s installed or not by running import cv2 in the notebook.


回答 7

我遇到了同样的问题docker这些步骤对我有用:

apt update

然后:

apt install libsm6 libxext6 libxrender-dev

I had the same problem in docker and these steps worked for me:

apt update

then:

apt install libsm6 libxext6 libxrender-dev

模块可以具有与对象相同的属性吗?

问题:模块可以具有与对象相同的属性吗?

使用python属性,我可以做到

obj.y 

调用一个函数,而不只是返回一个值。

有没有办法用模块来做到这一点?我有一个想要的情况

module.y 

调用一个函数,而不仅仅是返回存储在那里的值。

With python properties, I can make it such that

obj.y 

calls a function rather than just returning a value.

Is there a way to do this with modules? I have a case where I want

module.y 

to call a function, rather than just returning the value stored there.


回答 0

只有新式类的实例才能具有属性。通过将其存储在中,可以使Python相信这样的实例是模块sys.modules[thename] = theinstance。因此,例如,您的m.py模块文件可能是:

import sys

class _M(object):
    def __init__(self):
        self.c = 0
    def afunction(self):
        self.c += 1
        return self.c
    y = property(afunction)

sys.modules[__name__] = _M()

Only instances of new-style classes can have properties. You can make Python believe such an instance is a module by stashing it in sys.modules[thename] = theinstance. So, for example, your m.py module file could be:

import sys

class _M(object):
    def __init__(self):
        self.c = 0
    def afunction(self):
        self.c += 1
        return self.c
    y = property(afunction)

sys.modules[__name__] = _M()

回答 1

我这样做是为了正确继承模块的所有属性,并由isinstance()正确识别

import types

class MyModule(types.ModuleType):
    @property
    def y(self):
        return 5


>>> a=MyModule("test")
>>> a
<module 'test' (built-in)>
>>> a.y
5

然后可以将其插入sys.modules中:

sys.modules[__name__] = MyModule(__name__)  # remember to instantiate the class

I would do this in order to properly inherit all the attributes of a module, and be correctly identified by isinstance()

import types

class MyModule(types.ModuleType):
    @property
    def y(self):
        return 5


>>> a=MyModule("test")
>>> a
<module 'test' (built-in)>
>>> a.y
5

And then you can insert this into sys.modules:

sys.modules[__name__] = MyModule(__name__)  # remember to instantiate the class

回答 2

由于PEP 562已在Python> = 3.7中实现,现在我们可以执行此操作

文件:module.py

def __getattr__(name):
    if name == 'y':
        return 3
    raise AttributeError(f"module '{__name__}' has no attribute '{name}'")

other = 4

用法:

>>> import module
>>> module.y
3
>>> module.other
4
>>> module.nosuch
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "module.py", line 4, in __getattr__
    raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
AttributeError: module 'module' has no attribute 'nosuch'

请注意,如果您raise AttributeError__getattr__函数中省略,则表示函数以结束return None,则的module.nosuch值将为None

As PEP 562 has been implemented in Python >= 3.7, now we can do this

file: module.py

def __getattr__(name):
    if name == 'y':
        return 3
    raise AttributeError(f"module '{__name__}' has no attribute '{name}'")

other = 4

usage:

>>> import module
>>> module.y
3
>>> module.other
4
>>> module.nosuch
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "module.py", line 4, in __getattr__
    raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
AttributeError: module 'module' has no attribute 'nosuch'

Note that if you omit the raise AttributeError in the __getattr__ function, it means the function ends with return None, then the module.nosuch will get a value of None.


回答 3

根据约翰·林的回答

def module_property(func):
    """Decorator to turn module functions into properties.
    Function names must be prefixed with an underscore."""
    module = sys.modules[func.__module__]

    def base_getattr(name):
        raise AttributeError(
            f"module '{module.__name__}' has no attribute '{name}'")

    old_getattr = getattr(module, '__getattr__', base_getattr)

    def new_getattr(name):
        if f'_{name}' == func.__name__:
            return func()
        else:
            return old_getattr(name)

    module.__getattr__ = new_getattr
    return func

用法(请注意下划线),位于the_module.py

@module_property
def _thing():
    return 'hello'

然后:

import the_module

print(the_module.thing)  # prints 'hello'

前导下划线对于将属性化功能与原始功能区分开是必要的。我想不出一种重新分配标识符的方法,因为在执行装饰器的过程中,尚未分配它。

请注意,IDE不会知道该属性存在,并且会显示红色波形。

Based on John Lin’s answer:

def module_property(func):
    """Decorator to turn module functions into properties.
    Function names must be prefixed with an underscore."""
    module = sys.modules[func.__module__]

    def base_getattr(name):
        raise AttributeError(
            f"module '{module.__name__}' has no attribute '{name}'")

    old_getattr = getattr(module, '__getattr__', base_getattr)

    def new_getattr(name):
        if f'_{name}' == func.__name__:
            return func()
        else:
            return old_getattr(name)

    module.__getattr__ = new_getattr
    return func

Usage (note the leading underscore), in the_module.py:

@module_property
def _thing():
    return 'hello'

Then:

import the_module

print(the_module.thing)  # prints 'hello'

The leading underscore is necessary to differentiate the property-ized function from the original function. I couldn’t think of a way to reassign the identifier, since during the time of the decorator execution, it has not been assigned yet.

Note that IDEs won’t know that the property exists and will show red wavies.


回答 4

一个典型的用例是:使用一些动态属性来丰富(庞大的)现有模块-而无需将所有模块内容转换为类布局。不幸的是,最简单的模块类补丁如sys.modules[__name__].__class__ = MyPropertyModule失败了TypeError: __class__ assignment: only for heap types。因此,需要重新创建模块。

这种方法无需使用Python导入钩子就能做到这一点,只需在模块代码的顶部添加一些序言即可:

# propertymodule.py
""" Module property example """

if '__orgmod__' not in globals():

    # constant prolog for having module properties / supports reload()

    print "PropertyModule stub execution", __name__
    import sys, types
    class PropertyModule(types.ModuleType):
        def __str__(self):
            return "<PropertyModule %r from %r>" % (self.__name__, self.__file__)
    modnew = PropertyModule(__name__, __doc__)
    modnew.__modclass__ = PropertyModule        
    modnew.__file__ = __file__
    modnew.__orgmod__ = sys.modules[__name__]
    sys.modules[__name__] = modnew
    exec sys._getframe().f_code in modnew.__dict__

else:

    # normal module code (usually vast) ..

    print "regular module execution"
    a = 7

    def get_dynval(module):
        return "property function returns %s in module %r" % (a * 4, module.__name__)    
    __modclass__.dynval = property(get_dynval)

用法:

>>> import propertymodule
PropertyModule stub execution propertymodule
regular module execution
>>> propertymodule.dynval
"property function returns 28 in module 'propertymodule'"
>>> reload(propertymodule)   # AFTER EDITS
regular module execution
<module 'propertymodule' from 'propertymodule.pyc'>
>>> propertymodule.dynval
"property function returns 36 in module 'propertymodule'"

注意:类似的东西from propertymodule import dynval会产生一个冻结的过程,当然-与dynval = someobject.dynval

A typical use case is: enriching a (huge) existing module with some (few) dynamic attributes – without turning all module stuff into a class layout. Unfortunately a most simple module class patch like sys.modules[__name__].__class__ = MyPropertyModule fails with TypeError: __class__ assignment: only for heap types. So module creation needs to be rewired.

This approach does it without Python import hooks, just by having some prolog on top of the module code:

# propertymodule.py
""" Module property example """

if '__orgmod__' not in globals():

    # constant prolog for having module properties / supports reload()

    print "PropertyModule stub execution", __name__
    import sys, types
    class PropertyModule(types.ModuleType):
        def __str__(self):
            return "<PropertyModule %r from %r>" % (self.__name__, self.__file__)
    modnew = PropertyModule(__name__, __doc__)
    modnew.__modclass__ = PropertyModule        
    modnew.__file__ = __file__
    modnew.__orgmod__ = sys.modules[__name__]
    sys.modules[__name__] = modnew
    exec sys._getframe().f_code in modnew.__dict__

else:

    # normal module code (usually vast) ..

    print "regular module execution"
    a = 7

    def get_dynval(module):
        return "property function returns %s in module %r" % (a * 4, module.__name__)    
    __modclass__.dynval = property(get_dynval)

Usage:

>>> import propertymodule
PropertyModule stub execution propertymodule
regular module execution
>>> propertymodule.dynval
"property function returns 28 in module 'propertymodule'"
>>> reload(propertymodule)   # AFTER EDITS
regular module execution
<module 'propertymodule' from 'propertymodule.pyc'>
>>> propertymodule.dynval
"property function returns 36 in module 'propertymodule'"

Note: Something like from propertymodule import dynval will produce a frozen copy of course – corresponding to dynval = someobject.dynval


回答 5

一个简单的答案:使用 proxy_tools

proxy_tools软件包尝试提供@module_property功能。

它安装与

pip install proxy_tools

在@Marein的示例中,the_module.py我们 稍作修改

from proxy_tools import module_property

@module_property
def thing():
    print(". ", end='')  # Prints ". " on each invocation
    return 'hello'

现在,从另一个脚本中,我可以

import the_module

print(the_module.thing)
# . hello

意外行为

这个解决方案并非没有警告。也就是说,the_module.thing不是字符串!这是一个proxy_tools.Proxy对象,其特殊方法已被覆盖,因此它模仿字符串。这是一些说明点的基本测试:

res = the_module.thing
# [No output!!! Evaluation doesn't occur yet.]

print(type(res))
# <class 'proxy_tools.Proxy'>

print(isinstance(res, str))
# False

print(res)
# . hello

print(res + " there")
# . hello there

print(isinstance(res + "", str))
# . True

print(res.split('e'))
# . ['h', 'llo']

在内部,原始函数存储在 the_module.thing._Proxy__local

print(res._Proxy__local)
# <function thing at 0x7f729c3bf680>

进一步的想法

老实说,我对为什么模块没有内置此功能感到困惑。我认为问题的关键在于这the_moduletypes.ModuleType类的实例。设置“模块属性”等于在此类的实例上而不是在types.ModuleType类本身上设置属性。有关更多详细信息,请参见此答案

types.ModuleType尽管结果不是很好,但实际上我们可以按如下方式实现属性。我们不能直接修改内置类型,但是可以诅咒它们:

# python -m pip install forbiddenfruit
from forbiddenfruit import curse
from types import ModuleType
# curse has the same signature as setattr.
curse(ModuleType, "thing2", property(lambda module: f'hi from {module.__name__}'))

这为我们提供了一个存在于所有模块上的属性。这有点荒谬,因为我们打破了所有模块的设置行为:

import sys

print(sys.thing2)
# hi from sys

sys.thing2 = 5
# AttributeError: can't set attribute

A short answer: use proxy_tools

The proxy_tools package attempts to provide @module_property functionality.

It installs with

pip install proxy_tools

Using a slight modification of @Marein’s example, in the_module.py we put

from proxy_tools import module_property

@module_property
def thing():
    print(". ", end='')  # Prints ". " on each invocation
    return 'hello'

Now from another script, I can do

import the_module

print(the_module.thing)
# . hello

Unexpected behavior

This solution is not without caveats. Namely, the_module.thing is not a string! It is a proxy_tools.Proxy object whose special methods have been overridden so that it mimicks a string. Here are some basic tests which illustrate the point:

res = the_module.thing
# [No output!!! Evaluation doesn't occur yet.]

print(type(res))
# <class 'proxy_tools.Proxy'>

print(isinstance(res, str))
# False

print(res)
# . hello

print(res + " there")
# . hello there

print(isinstance(res + "", str))
# . True

print(res.split('e'))
# . ['h', 'llo']

Internally, the original function is stored to the_module.thing._Proxy__local:

print(res._Proxy__local)
# <function thing at 0x7f729c3bf680>

Further thoughts

Honestly, I’m baffled about why modules don’t have this functionality built in. I think the crux of the matter is that the_module is an instance of the types.ModuleType class. Setting a “module property” amounts to setting a property on an instance of this class, rather than on the types.ModuleType class itself. For more details, see this answer.

We can actually implement properties on types.ModuleType as follows, although the results are not great. We can’t directly modify built-in types, but we can curse them:

# python -m pip install forbiddenfruit
from forbiddenfruit import curse
from types import ModuleType
# curse has the same signature as setattr.
curse(ModuleType, "thing2", property(lambda module: f'hi from {module.__name__}'))

This gives us a property which exists over all modules. It’s a bit unwieldly, since we break the setting behavior across all modules:

import sys

print(sys.thing2)
# hi from sys

sys.thing2 = 5
# AttributeError: can't set attribute

无法导入明确安装的模块

问题:无法导入明确安装的模块

安装机械化后,我似乎无法导入它。

我已经尝试从pip,easy_install和通过python setup.py install此仓库通过https://github.com/abielr/mechanize安装。所有这些都无济于事,因为每次我输入Python交互式代码时,都会得到:

Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mechanize
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named mechanize
>>> 

我之前运行的安装报告说它们已成功完成,因此我希望导入工作正常。是什么导致此错误?

After installing mechanize, I don’t seem to be able to import it.

I have tried installing from pip, easy_install, and via python setup.py install from this repo: https://github.com/abielr/mechanize. All of this to no avail, as each time I enter my Python interactive I get:

Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mechanize
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named mechanize
>>> 

The installations I ran previously reported that they had completed successfully, so I expect the import to work. What could be causing this error?


回答 0

就我而言,这是权限问题。该软件包以某种方式仅具有root rw权限安装,其他用户则无法rw!

In my case, it is permission problem. The package was somehow installed with root rw permission only, other user just cannot rw to it!


回答 1

我遇到了同样的问题:脚本import colorama被抛出并且导入错误,但是sudo pip install colorama告诉我“软件包已安装”。

我的解决方法:在不使用sudo:的情况下运行pip pip install colorama。然后pip同意需要安装它,然后安装它,然后我的脚本运行了。

我的环境是32位Ubuntu 14.04;我想我在激活virtualenv之前和之后都看到了这个。

更新:甚至更好,使用python -m pip install <package>。这样做的好处是,由于您正在执行要在其中安装软件包的特定版本的python,因此pip会明确将软件包安装到“正确的” python中。同样,在这种情况下,请不要使用sudo …然后您将软件包放在正确的位置,但可能具有(不需要的)root权限。

I had the same problem: script with import colorama was throwing and ImportError, but sudo pip install colorama was telling me “package already installed”.

My fix: run pip without sudo: pip install colorama. Then pip agreed it needed to be installed, installed it, and my script ran.

My environment is Ubuntu 14.04 32-bit; I think I saw this before and after I activated my virtualenv.

UPDATE: even better, use python -m pip install <package>. The benefit of this is, since you are executing the specific version of python that you want the package in, pip will unequivocally install the package in to the “right” python. Again, don’t use sudo in this case… then you get the package in the right place, but possibly with (unwanted) root permissions.


回答 2

这是python路径问题。

就我而言,我在以下位置安装了python:

/Library/Frameworks/Python.framework/Versions/2.6/bin/python,

并且python2.6中没有site-packages目录。

我通过pip安装的包(SOAPpy)位于

/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/

而且site-package不在python路径中,我所做的就是将site-packages永久添加到PYTHONPATH中。

  1. 打开终端
  2. 输入open .bash_profile
  3. 在弹出的文本文件中,在最后添加以下行:

    导出PYTHONPATH = $ PYTHONPATH:/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/

  4. 保存文件,重新启动终端,然后完成

It’s the python path problem.

In my case, I have python installed in:

/Library/Frameworks/Python.framework/Versions/2.6/bin/python,

and there is no site-packages directory within the python2.6.

The package(SOAPpy) I installed by pip is located

/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/

And site-package is not in the python path, all I did is add site-packages to PYTHONPATH permanently.

  1. Open up Terminal
  2. Type open .bash_profile
  3. In the text file that pops up, add this line at the end:

    export PYTHONPATH=$PYTHONPATH:/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/

  4. Save the file, restart the Terminal, and you’re done

回答 3

实际上,Python导入机制可以运行:

  1. 您的PYTHONPATH错误,
  2. 您的库未安装在您认为的位置
  3. 您有另一个同名的库掩盖了这个库

The Python import mechanism works, really, so, either:

  1. Your PYTHONPATH is wrong,
  2. Your library is not installed where you think it is
  3. You have another library with the same name masking this one

回答 4

我一直把头撞在显示器上,直到一位年轻的实习生告诉我,秘密是在模块目录中 “ python setup.py install”

由于某些原因,从那里运行安装程序使其可以正常工作。

要明确的是,如果模块的名称是“ foo”:

[burnc7 (2016-06-21 15:28:49) git]# ls -l
total 1
drwxr-xr-x 7 root root  118 Jun 21 15:22 foo
[burnc7 (2016-06-21 15:28:51) git]# cd foo
[burnc7 (2016-06-21 15:28:53) foo]# ls -l
total 2
drwxr-xr-x 2 root root   93 Jun 21 15:23 foo
-rw-r--r-- 1 root root  416 May 31 12:26 setup.py
[burnc7 (2016-06-21 15:28:54) foo]# python setup.py install
<--snip-->

如果尝试通过调出路径从任何其他目录运行setup.py,最终将导致安装失败。

不起作用:

python /root/foo/setup.py install

运作方式:

cd /root/foo
python setup.py install

I have been banging my head against my monitor on this until a young-hip intern told me the secret is to “python setup.py install” inside the module directory.

For some reason, running the setup from there makes it just work.

To be clear, if your module’s name is “foo”:

[burnc7 (2016-06-21 15:28:49) git]# ls -l
total 1
drwxr-xr-x 7 root root  118 Jun 21 15:22 foo
[burnc7 (2016-06-21 15:28:51) git]# cd foo
[burnc7 (2016-06-21 15:28:53) foo]# ls -l
total 2
drwxr-xr-x 2 root root   93 Jun 21 15:23 foo
-rw-r--r-- 1 root root  416 May 31 12:26 setup.py
[burnc7 (2016-06-21 15:28:54) foo]# python setup.py install
<--snip-->

If you try to run setup.py from any other directory by calling out its path, you end up with a borked install.

DOES NOT WORK:

python /root/foo/setup.py install

DOES WORK:

cd /root/foo
python setup.py install

回答 5

我能够通过组合方法解决此问题。首先,我遵循Chris的建议,打开了一个命令行,然后键入“ pip show packagename”。这提供了已安装软件包的位置。

接下来,我打开python并键入“ import sys”,然后键入“ sys.path”以显示我的python在哪里搜索我导入的任何软件包。las,第一步中显示的位置不在列表中。

最后一步,我输入了“ sys.path.append(’package_location_seen_in_step_1’)。您可以选择重复第二步,以查看该位置现在在列表中。

测试步骤,尝试再次导入包…。

不足之处?它是临时的,您需要每次将其添加到列表中。

I was able to correct this issue with a combined approach. First, I followed Chris’ advice, opened a command line and typed ‘pip show packagename’ This provided the location of the installed package.

Next, I opened python and typed ‘import sys’, then ‘sys.path’ to show where my python searches for any packages I import. Alas, the location shown in the first step was NOT in the list.

Final step, I typed ‘sys.path.append(‘package_location_seen_in_step_1’). You optionally can repeat step two to see the location is now in the list.

Test step, try to import the package again… it works.

The downside? It is temporary, and you need to add it to the list each time.


回答 6

我在尝试使用通过安装的密钥环时遇到了此问题sudo pip install keyring。如其他答案所述,在我看来,这是一个权限问题。

对我有用的是:

  1. 卸载密钥环:
    • sudo pip uninstall keyring
  2. 我使用了sudo的-H选项并重新安装了密钥环:
    • sudo -H pip install keyring

希望这可以帮助。

I encountered this while trying to use keyring which I installed via sudo pip install keyring. As mentioned in the other answers, it’s a permissions issue in my case.

What worked for me:

  1. Uninstalled keyring:
    • sudo pip uninstall keyring
  2. I used sudo’s -H option and reinstalled keyring:
    • sudo -H pip install keyring

Hope this helps.


回答 7

我是python的新手。我通过更改项目解释器路径来解决此问题。
File -> Settings -> Project -> Project Interpreter

I am new to python. I fixed this issue by changing the project interpreter path.
File -> Settings -> Project -> Project Interpreter


回答 8

我的PYTHONPATH无法正常工作。我意识到添加export解决了这个问题:

(工作)

export PYTHONPATH=$PYTHONPATH:~/test/site-packages

(不工作)

PYTHONPATH=$PYTHONPATH:~/test/site-packages

I couldn’t get my PYTHONPATH to work properly. I realized adding export fixed the issue:

(did work)

export PYTHONPATH=$PYTHONPATH:~/test/site-packages

vs.

(did not work)

PYTHONPATH=$PYTHONPATH:~/test/site-packages

回答 9

就我而言,我已经运行了pip install Django==1.11,并且不会从python解释器导入。

浏览pip的命令后发现pip show

> pip show Django
Name: Django
Version: 1.11
...
Location: /usr/lib/python3.4/site-packages
...

注意该位置显示为“ 3.4”。我发现python-command链接到python2.7

/usr/bin> ls -l python
lrwxrwxrwx 1 root root 9 Mar 14 15:48 python -> python2.7

在它旁边,我找到了一个链接,python3所以我使用了它。您也可以将链接更改为python3.4。那也可以解决。

In my case I had run pip install Django==1.11 and it would not import from the python interpreter.

Browsing through pip’s commands I found pip show which looked like this:

> pip show Django
Name: Django
Version: 1.11
...
Location: /usr/lib/python3.4/site-packages
...

Notice the location says ‘3.4’. I found that the python-command was linked to python2.7

/usr/bin> ls -l python
lrwxrwxrwx 1 root root 9 Mar 14 15:48 python -> python2.7

Right next to that I found a link called python3 so I used that. You could also change the link to python3.4. That would fix it, too.


回答 10

就我而言,这是一个模块缺少init .py文件的问题,我想在Python 2.7环境中导入该文件。

Python 3.3+具有隐式命名空间包,允许它创建没有init .py文件的包。

In my case it was a problem with a missing init.py file in the module, that I wanted to import in a Python 2.7 environment.

Python 3.3+ has Implicit Namespace Packages that allow it to create a packages without an init.py file.


回答 11

如果提到的其他答案对您不起作用,请尝试删除您的点子缓存并重新安装软件包。我的机器运行Ubuntu14.04,它位于下~/.cache/pip。删除此文件夹对我有用。

If the other answers mentioned do not work for you, try deleting your pip cache and reinstalling the package. My machine runs Ubuntu14.04 and it was located under ~/.cache/pip. Deleting this folder did the trick for me.


回答 12

另外,请确保您不要pip3与混淆pip。我发现安装的软件包pip无法正常工作,python3反之亦然。

Also, make sure that you do not confuse pip3 with pip. What I found was that package installed with pip was not working with python3 and vice-versa.


回答 13

通过easy_install或安装时pip,是否成功完成?全部输出是多少?您正在使用哪个python安装?sudo如果要将模块安装到系统目录中,则可能需要在安装命令前使用(如果使用的是系统python安装)。您的问题中没有很多有用的信息,但是一些可能会有所帮助的工具包括:

  • echo $PYTHONPATH和/或echo $PATH:导入模块时,Python在这些环境变量之一(目录列表,带:分隔符)中搜索所需的模块。导入问题通常是由于这些列表中缺少正确的目录

  • which pythonwhich pipwhich easy_install:这些将告诉您每个可执行文件的位置。可能会有所帮助。

  • 使用virtualenv,就像@JesseBriggs建议的那样。它可以很好pip地帮助您隔离和管理单独的Python项目的模块和环境。

When you install via easy_install or pip, is it completing successfully? What is the full output? Which python installation are you using? You may need to use sudo before your installation command, if you are installing modules to a system directory (if you are using the system python installation, perhaps). There’s not a lot of useful information in your question to go off of, but some tools that will probably help include:

  • echo $PYTHONPATH and/or echo $PATH: when importing modules, Python searches one of these environment variables (lists of directories, : delimited) for the module you want. Importing problems are often due to the right directory being absent from these lists

  • which python, which pip, or which easy_install: these will tell you the location of each executable. It may help to know.

  • Use virtualenv, like @JesseBriggs suggests. It works very well with pip to help you isolate and manage the modules and environment for separate Python projects.


回答 14

我遇到了这个确切的问题,但以上答案均无济于事。这使我发疯,直到我从父项目中导入后发现sys.path有所不同。原来,我已经使用importlib编写了一个小功能,以便导入不在项目层次结构中的文件。坏主意:我忘记了这样做。更糟糕的是,导入过程与sys.path混为一谈,并以这种方式保留了下来。非常糟糕的主意。

解决方案是停止此操作,只需将需要导入的文件放入项目中即可。另一种方法是将文件放入其自己的项目中,因为需要不时地对其进行重建,并且该重建与主项目的重建可能会也可能不会同时进行。

I had this exact problem, but none of the answers above worked. It drove me crazy until I noticed that sys.path was different after I had imported from the parent project. It turned out that I had used importlib to write a little function in order to import a file not in the project hierarchy. Bad idea: I forgot that I had done this. Even worse, the import process mucked with the sys.path–and left it that way. Very bad idea.

The solution was to stop that, and simply put the file I needed to import into the project. Another approach would have been to put the file into its own project, as it needs to be rebuilt from time to time, and the rebuild may or may not coincide with the rebuild of the main project.


回答 15

我在系统上安装了2.7和3.5时遇到了这个问题,试图用Python-Telegram-Bot测试电报机器人。

使用pip和pip3(使用sudo或不使用sip)安装后,我无法正常工作。我总是得到:

Traceback (most recent call last):
  File "telegram.py", line 2, in <module>
    from telegram.ext import Updater
  File "$USER/telegram.py", line 2, in <module>
    from telegram.ext import Updater
ImportError: No module named 'telegram.ext'; 'telegram' is not a package

正确阅读错误消息告诉我python正在当前目录中查找telegram.py。正确的是,我那里有一个名为telegram.py的脚本,当我调用时,该脚本由python加载import

结论,请确保package.py在尝试导入时当前目录中没有任何内容。(并仔细阅读错误消息)。

I had this problem with 2.7 and 3.5 installed on my system trying to test a telegram bot with Python-Telegram-Bot.

I couldn’t get it to work after installing with pip and pip3, with sudo or without. I always got:

Traceback (most recent call last):
  File "telegram.py", line 2, in <module>
    from telegram.ext import Updater
  File "$USER/telegram.py", line 2, in <module>
    from telegram.ext import Updater
ImportError: No module named 'telegram.ext'; 'telegram' is not a package

Reading the error message correctly tells me that python is looking in the current directory for a telegram.py. And right, I had a script lying there called telegram.py and this was loaded by python when I called import.

Conclusion, make sure you don’t have any package.py in your current working dir when trying to import. (And read error message thoroughly).


回答 16

我有类似的问题(在Windows上),根本原因是ANTIVIRUS软件!它具有“自动包含”功能,该功能将运行过程与某种虚拟机进行包装。症状是:pip install somemodule在一个cmd-line窗口中工作正常,并且import somemodule在从另一个进程执行时出现错误而失败

ModuleNotFoundError: No module named 'somemodule'

我希望这可以节省一些时间:)

I had similar problem (on Windows) and the root cause in my case was ANTIVIRUS software! It has “Auto-Containment” feature, that wraps running process with some kind of a virtual machine. Symptoms are: pip install somemodule works fine in one cmd-line window and import somemodule fails when executed from another process with the error

ModuleNotFoundError: No module named 'somemodule'

I hope it will save some time to somebody :)


回答 17

也许有点题外话,但我遇到了一些问题import PyYAML。指出您需要import yaml。(猜测这是经典的rtfm …)

Maybe a bit off-topic, but i had issues to import PyYAML. Points out that you need to import yaml. (guess it’s a classical rtfm…)


回答 18

我在使用Django时遇到类似的问题。就我而言,我可以从Django Shell导入模块,但不能从导入模块的.py导入。
问题是我从安装模块的另一个virtualenv运行Django服务器(因此,执行.py)。

相反,shell实例是在正确的virtualenv中运行的。因此,它为什么起作用。

I had a similar problem using Django. In my case, I could import the module from the Django shell, but not from a .py which imported the module.
The problem was that I was running the Django server (therefore, executing the .py) from a different virtualenv from which the module had been installed.

Instead, the shell instance was being run in the correct virtualenv. Hence, why it worked.


回答 19

这有效!!!

当模块安装到旧版本的python或另一个目录时,通常会发生这种情况,因为解决方案很简单,所以不用担心。-从安装模块的目录中导入模块。您可以先导入python sys模块,然后从模块安装路径导入

import sys
sys.path.append("directory in which module is installed")

import <module_name>

This Works!!!

This often happens when module is installed to an older version of python or another directory, no worries as solution is simple. – import module from directory in which module is installed. You can do this by first importing the python sys module then importing from the path in which the module is installed

import sys
sys.path.append("directory in which module is installed")

import <module_name>

回答 20

解决方案中已经涵盖了大多数可能的情况,只是分享我的情况,我碰巧在一个环境(例如X)中安装了一个软件包,而在另一个环境(例如)中导入了该软件包Y。因此,请始终确保从安装软件包的环境中导入软件包。

Most of the possible cases have been already covered in solutions, just sharing my case, it happened to me that I installed a package in one environment (e.g. X) and I was importing the package in another environment (e.g. Y). So, always make sure that you’re importing the package from the environment in which you installed the package.


回答 21

对我有用的是:

python -m pip install -user {package name}

该命令不需要sudo。这已在OSX Mojave上进行了测试。

Something that worked for me was:

python -m pip install -user {package name}

The command does not require sudo. This was tested on OSX Mojave.


回答 22

就我而言,我也必须为超级用户安装模块。

sudo su
pip install <module>

显然,在某些情况下,superuse无法访问普通用户文件。

In my case I had to also install the module(s) for the superuser, too.

sudo su
pip install <module>

Apparently the superuse cannot access the normal users files under certain circumstances.


回答 23

对我来说,这是确保模块的版本与我使用的Python版本保持一致。.我在装有Python 3.6的盒子上构建了映像,然后注入恰好安装了3.7的Docker映像中,然后敲了敲我的头当Python告诉我模块未安装时…

36m 适用于Python 3.6 bsonnumpy.cpython-36m-x86_64-linux-gnu.so

37m 对于Python 3.7 bsonnumpy.cpython-37m-x86_64-linux-gnu.so

For me it was ensuring the version of the module aligned with the version of Python I was using.. I built the image on a box with Python 3.6 and then injected into a Docker image that happened to have 3.7 installed, and then banging my head when Python was telling me the module wasn’t installed…

36m for Python 3.6 bsonnumpy.cpython-36m-x86_64-linux-gnu.so

37m for Python 3.7 bsonnumpy.cpython-37m-x86_64-linux-gnu.so


回答 24

我知道这是一篇非常老的文章,但是对我来说,我遇到了安装32位python和64位python的问题。一旦我卸载了32位python,一切都会正常进行。

I know this is a super old post but for me, I had an issue with a 32 bit python and 64 bit python installed. Once I uninstalled the 32 bit python, everything worked as it should.


回答 25

我已经解决了一个问题,即相同的库在一个项目(A)中运行良好,但是将这些相同的库导入另一个项目(B)却导致错误。我在Windows OS上使用Pycharm作为IDE。因此,在尝试了许多潜在的解决方案并且未能解决问题之后,我做了这两件事(删除了“ Venv”文件夹,并重新配置了解释器):

1-在项目(B)中,位于外部库/中有一个名为(“ venv”)的文件夹。我删除了那个文件夹。

2步1(删除“ venv”文件夹)在Python解释器配置中导致错误,并且屏幕顶部显示一条消息,提示“为项目选择了无效的python解释器”和“配置python解释器”,选择该链接并打开一个新窗口。在“项目解释器”下拉列表中,有一条红色的线显示了先前的无效解释器。现在,打开此列表并选择Python解释器(在我的情况下是Python 3.7)。按下底部的“应用”和“确定”,您就可以开始了。

注意:这可能是我的项目(B)的虚拟环境无法识别已经安装且正在运行的库的问题。

I have solved my issue that same libraries were working fine in one project(A) but importing those same libraries in another project(B) caused error. I am using Pycharm as IDE at Windows OS. So, after trying many potential solutions and failing to solve the issue, I did these two things (deleted “Venv” folder, and reconfigured interpreter):

1-In project(B), there was a folder named(“venv”), located in External Libraries/. I deleted that folder.

2-Step 1 (deleting “venv” folder) causes error in Python Interpreter Configuration, and there is a message shown at top of screen saying “Invalid python interpreter selected for the project” and “configure python interpreter”, select that link and it opens a new window. There in “Project Interpreter” drop-down list, there is a Red colored line showing previous invalid interpreter. Now, Open this list and select the Python Interpreter(in my case, it is Python 3.7). Press “Apply” and “OK” at the bottom and you are good to go.

Note: It was potentially the issue where Virtual Environment of my Project(B) was not recognizing the already installed and working libraries.


回答 26

如果您使用的是虚拟环境,请使用pipenv install <module name>而不是pip install <module name>

为我工作。

If you are using a virtual environment use pipenv install <module name> instead of pip install <module name>

Worked for me.


回答 27

也有这个问题。.该软件包安装在Python 3.8.0上,但是VS Code使用较旧的版本(3.4)运行我的脚本

在终端中修复:

py .py

确保您在正确的Python版本上安装了软件包

Had this problem too.. the package was installed on Python 3.8.0 but VS Code was running my script using an older version (3.4)

fix in terminal:

py .py

Make sure you’re installing the package on the right Python Version


回答 28

就像今天朋友为我所做的那样,这对我有所帮助(我正在使用Windows):

按“设置”->“项目”->“项目解释器”。在右边的窗口中,左边有一行标题为“ Project Interpreter”的行。单击此行,它将打开其他几行。

现在按“显示全部”行。将会打开一个窗口。在此窗口中,按右上角的小“ +”号。

将打开一个新窗口。在左侧,有4个选项卡,按最上面的一个,即“ Virtualenv Environment”。现在,在右侧窗口中,标记“现有环境”选项。“翻译”行将变得清晰可见。按下该行右侧的“ …”按钮。

现在,将打开一个浏览窗口。浏览到在其中安装Python本身的目录。不是拥有PyCharm的人。当您到达那里时,选择“ python.exe”文件,然后按OK(该窗口将消失)。

再次按OK(此窗口也将消失)。

现在,在此窗口中,确保标记了您创建的新行,然后再次按OK。

现在,所有已安装的软件包都应该在项目解释器中可见,并由您的程序读取。

As a friend did for me today, here is what helped me (I am using Windows):

Press ‘Setting’ -> ‘Project’ -> ‘Project Interpreter’. Here in the window on the right, there is a line with the title ‘Project Interpreter’ on it’s left. Click this line and it will open several additional lines.

Now press the ‘Show All’ line. A window will open. In this window press the small ‘+’ sign in the upper right corner.

A new window will open. On the left there are 4 tabs, press the most upper one, which says ‘Virtualenv Environment’. Now, in the window on the right, mark the ‘Existing Environment’ option. The ‘Interpreter’ line will become well visible. Press the ‘…’ button on the right of the line.

Now, a browsing window will open. Browse to the directory that you installed Python itself in. Not the one with PyCharm. When you get there, choose the ‘python.exe’ file and press OK (the window will disappear).

Press OK again (this window will disappear too).

Now in this window make sure the new line you created is marked, and press OK again.

Now, all the installed packages should be visible in the project interpreter, and are read by your program.


回答 29

在这个线程中没有提到对我有用的最简单的解决方案:

我安装了多个版本的Python,但尝试使用Python3.7-所以我不得不使用:

sudo pip3.7 install <package>

Simplest solution that worked for me that I don’t see mentioned in this thread:

I have multiple versions of Python installed but was trying to use Python3.7 — so I had to use:

sudo pip3.7 install <package>


在代码中安装python模块

问题:在代码中安装python模块

我需要直接在脚本中从PyPi安装软件包。也许有一些模块或distutilsdistributepip等)功能使我可以执行类似的操作,pypi.install('requests')并且请求将被安装到我的virtualenv中。

I need to install a package from PyPi straight within my script. Maybe there’s some module or distutils (distribute, pip etc.) feature which allows me to just execute something like pypi.install('requests') and requests will be installed into my virtualenv.


回答 0

从脚本安装软件包的官方推荐方法是通过子进程调用pip的命令行界面。pip不支持此处提出的大多数其他答案。此外,自pip v10起,所有代码都已pip._internal精确定位,以使用户清楚不允许以编程方式使用pip。

使用sys.executable,以确保您将调用相同pip与当前运行相关联。

import subprocess
import sys

def install(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])

The officially recommended way to install packages from a script is by calling pip’s command-line interface via a subprocess. Most other answers presented here are not supported by pip. Furthermore since pip v10, all code has been moved to pip._internal precisely in order to make it clear to users that programmatic use of pip is not allowed.

Use sys.executable to ensure that you will call the same pip associated with the current runtime.

import subprocess
import sys

def install(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])

回答 1

您还可以使用类似:

import pip

def install(package):
    if hasattr(pip, 'main'):
        pip.main(['install', package])
    else:
        pip._internal.main(['install', package])

# Example
if __name__ == '__main__':
    install('argh')

You can also use something like:

import pip

def install(package):
    if hasattr(pip, 'main'):
        pip.main(['install', package])
    else:
        pip._internal.main(['install', package])

# Example
if __name__ == '__main__':
    install('argh')

回答 2

如果要用于pip安装所需的软件包并在安装后将其导入,则可以使用以下代码:

def install_and_import(package):
    import importlib
    try:
        importlib.import_module(package)
    except ImportError:
        import pip
        pip.main(['install', package])
    finally:
        globals()[package] = importlib.import_module(package)


install_and_import('transliterate')

如果您以用户身份安装软件包,则可能会遇到不能仅导入软件包的问题。请参阅如何刷新sys.path?有关其他信息。

If you want to use pip to install required package and import it after installation, you can use this code:

def install_and_import(package):
    import importlib
    try:
        importlib.import_module(package)
    except ImportError:
        import pip
        pip.main(['install', package])
    finally:
        globals()[package] = importlib.import_module(package)


install_and_import('transliterate')

If you installed a package as a user you can encounter the problem that you cannot just import the package. See How to refresh sys.path? for additional information.


回答 3

这应该工作:

import subprocess

def install(name):
    subprocess.call(['pip', 'install', name])

This should work:

import subprocess

def install(name):
    subprocess.call(['pip', 'install', name])

回答 4

我在@Aaron的答案中添加了一些异常处理。

import subprocess
import sys

try:
    import pandas as pd
except ImportError:
    subprocess.check_call([sys.executable, "-m", "pip", "install", 'pandas'])
finally:
    import pandas as pd

i added some exception handling to @Aaron’s answer.

import subprocess
import sys

try:
    import pandas as pd
except ImportError:
    subprocess.check_call([sys.executable, "-m", "pip", "install", 'pandas'])
finally:
    import pandas as pd

回答 5

您可以使用“ install_requires”选项在自己程序包的setup.py中定义从属模块。

如果您的软件包需要生成一些控制台脚本,则可以使用“ console_scripts”入口点来生成包装脚本,该脚本将被放置在“ bin”文件夹(例如您的virtualenv环境)中。

You define the dependent module inside the setup.py of your own package with the “install_requires” option.

If your package needs to have some console script generated then you can use the “console_scripts” entry point in order to generate a wrapper script that will be placed within the ‘bin’ folder (e.g. of your virtualenv environment).


如何编写Python模块/软件包?

问题:如何编写Python模块/软件包?

我一直在为工作中的简单任务制作Python脚本,从来没有真正打扰过将它们打包供其他人使用。现在,我被分配为REST API制作Python包装器。我对如何开始一无所知,我需要帮助。

我有的:

(只想尽可能地具体一点)我已经准备好virtualenv,它也位于github上,还存在用于python的.gitignore文件,以及用于与REST API交互的请求库。而已。

这是当前目录树

.
├── bin
   └── /the usual stuff/
├── include
   └── /the usual stuff/
├── lib
   └── python2.7
       └── /the usual stuff/
├── local
   └── /the usual stuff/
└── README.md

27 directories, 280 files

我什至不知道将.py文件放在哪里。

我想做的是:

使用“ pip install …”制作可安装的python模块

如果可能的话,我需要一个逐步的编写Python模块的逐步过程。

I’ve been making Python scripts for simple tasks at work and never really bothered packaging them for others to use. Now I have been assigned to make a Python wrapper for a REST API. I have absolutely no idea on how to start and I need help.

What I have:

(Just want to be specific as possible) I have the virtualenv ready, it’s also up in github, the .gitignore file for python is there as well, plus, the requests library for interacting with the REST API. That’s it.

Here’s the current directory tree

.
├── bin
│   └── /the usual stuff/
├── include
│   └── /the usual stuff/
├── lib
│   └── python2.7
│       └── /the usual stuff/
├── local
│   └── /the usual stuff/
└── README.md

27 directories, 280 files

I don’t even know where to put the .py files, if I ever make one.

What I wanted to do:

Make a python module install-able with “pip install …”

If possible, I want a general step by step process on writing Python modules.


回答 0

模块是包含Python定义和语句的文件。文件名是带有后缀的模块名称.py

创建hello.py然后编写以下函数作为其内容:

def helloworld():
   print "hello"

然后,您可以导入hello

>>> import hello
>>> hello.helloworld()
'hello'
>>>

要对许多.py文件进行分组,请将它们放在文件夹中。带有的任何文件夹__init__.py都被python视为模块,您可以将其称为包

|-HelloModule
  |_ __init__.py
  |_ hellomodule.py

您可以按照通常的方式在模块上使用import语句。

有关更多信息,请参见6.4。包

A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py

create hello.py then write the following function as its content:

def helloworld():
   print "hello"

Then you can import hello:

>>> import hello
>>> hello.helloworld()
'hello'
>>>

To group many .py files put them in a folder. Any folder with an __init__.py is considered a module by python and you can call them a package

|-HelloModule
  |_ __init__.py
  |_ hellomodule.py

You can go about with the import statement on your module the usual way.

For more information, see 6.4. Packages.


回答 1

Python 3-更新于2015年11月18日

认为已接受的答案很有用,但希望根据我自己的经验在几个方面进行扩展,以使他人受益。

模块:模块是包含Python定义和语句的文件。文件名是模块名称,后缀.py。

模块示例:假设我们在当前目录中只有一个python脚本,在这里我将其称为mymodule.py

文件mymodule.py包含以下代码:

def myfunc():
    print("Hello!")

如果我们从当前目录运行python3解释器,则可以通过以下不同方式导入和运行函数myfunc(通常,您只需选择以下一种):

>>> import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mymodule import myfunc
>>> myfunc()
Hello!
>>> from mymodule import *
>>> myfunc()
Hello!

好的,这很容易。

现在假设您需要将该模块放入其自己的专用文件夹中以提供模块命名空间,而不是仅从当前工作目录中临时运行它。这是值得解释软件包概念的地方。

:包是通过使用“点分模块名称”来构造Python模块命名空间的一种方式。例如,模块名称AB在名为A的包中指定了一个名为B的子模块。就像使用模块使不同模块的作者免于担心彼此的全局变量名一样,使用带点划线的模块名称也节省了作者诸如NumPy或Python Imaging Library之类的多模块软件包,而不必担心彼此的模块名称。

包示例:现在假设我们具有以下文件夹和文件。在这里,mymodule.py与以前相同,并且__init__.py是一个空文件:

.
└── mypackage
    ├── __init__.py
    └── mymodule.py

__init__.py文件是使Python将目录视为包含包的必需文件。有关更多信息,请参见稍后提供的模块文档链接。

我们当前的工作目录位于名为mypackage的普通文件夹之上的一级

$ ls
mypackage

如果现在运行python3解释器,则可以通过以下不同方式导入并运行包含所需函数myfunc的模块mymodule.py(通常,您只需选择以下一种):

>>> import mypackage
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> import mypackage.mymodule
>>> mypackage.mymodule.myfunc()
Hello!
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mypackage.mymodule import myfunc
>>> myfunc()
Hello!
>>> from mypackage.mymodule import *
>>> myfunc()
Hello!

假设使用Python 3,以下位置提供了出色的文档:模块

关于程序包和模块的命名约定,PEP-0008中给出了通用准则-请参阅程序包和模块名称

模块应使用简短的全小写名称。如果模块名称可以提高可读性,则可以在模块名称中使用下划线。尽管不鼓励使用下划线,但Python软件包也应使用短小写全名。

Python 3 – UPDATED 18th November 2015

Found the accepted answer useful, yet wished to expand on several points for the benefit of others based on my own experiences.

Module: A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py appended.

Module Example: Assume we have a single python script in the current directory, here I am calling it mymodule.py

The file mymodule.py contains the following code:

def myfunc():
    print("Hello!")

If we run the python3 interpreter from the current directory, we can import and run the function myfunc in the following different ways (you would typically just choose one of the following):

>>> import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mymodule import myfunc
>>> myfunc()
Hello!
>>> from mymodule import *
>>> myfunc()
Hello!

Ok, so that was easy enough.

Now assume you have the need to put this module into its own dedicated folder to provide a module namespace, instead of just running it ad-hoc from the current working directory. This is where it is worth explaining the concept of a package.

Package: Packages are a way of structuring Python’s module namespace by using “dotted module names”. For example, the module name A.B designates a submodule named B in a package named A. Just like the use of modules saves the authors of different modules from having to worry about each other’s global variable names, the use of dotted module names saves the authors of multi-module packages like NumPy or the Python Imaging Library from having to worry about each other’s module names.

Package Example: Let’s now assume we have the following folder and files. Here, mymodule.py is identical to before, and __init__.py is an empty file:

.
└── mypackage
    ├── __init__.py
    └── mymodule.py

The __init__.py files are required to make Python treat the directories as containing packages. For further information, please see the Modules documentation link provided later on.

Our current working directory is one level above the ordinary folder called mypackage

$ ls
mypackage

If we run the python3 interpreter now, we can import and run the module mymodule.py containing the required function myfunc in the following different ways (you would typically just choose one of the following):

>>> import mypackage
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> import mypackage.mymodule
>>> mypackage.mymodule.myfunc()
Hello!
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mypackage.mymodule import myfunc
>>> myfunc()
Hello!
>>> from mypackage.mymodule import *
>>> myfunc()
Hello!

Assuming Python 3, there is excellent documentation at: Modules

In terms of naming conventions for packages and modules, the general guidelines are given in PEP-0008 – please see Package and Module Names

Modules should have short, all-lowercase names. Underscores can be used in the module name if it improves readability. Python packages should also have short, all-lowercase names, although the use of underscores is discouraged.


回答 2

由于尚无人讨论过OP的这个问题:

我想做的是:

使用“ pip install …”制作可安装的python模块

这是一个绝对的最小示例,显示了使用setuptools和准备软件包并将其上传到PyPI的基本步骤twine

这绝不能代替阅读至少本教程,它比这个非常基本的示例所涵盖的内容要多得多。

在这里,其他答案已经涵盖了创建包本身,因此,让我们假设我们已经覆盖了这一步,并且我们的项目结构如下:

.
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

为了setuptools用于打包,我们需要添加一个文件setup.py,该文件进入我们项目的根文件夹:

.
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

至少,我们为包指定元数据,setup.py如下所示:

from setuptools import setup

setup(
    name='hellostackoverflow',
    version='0.0.1',
    description='a pip-installable package example',
    license='MIT',
    packages=['hellostackoverflow'],
    author='Benjamin Gerfelder',
    author_email='benjamin.gerfelder@gmail.com',
    keywords=['example'],
    url='https://github.com/bgse/hellostackoverflow'
)

设置好之后license='MIT',我们在项目中添加了一个副本,LICENCE.txt在reStructuredText中添加了一个自述文件,如下所示README.rst

.
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

此时,我们准备开始使用进行打包setuptools,如果尚未安装,可以使用以下命令进行安装pip

pip install setuptools

为了做到这一点并source distribution在项目的根文件夹中创建一个,我们setup.py从命令行调用我们,指定我们想要的sdist

python setup.py sdist

这将创建我们的分发程序包和egg-info,并导致这样的文件夹结构,我们的程序包位于dist

.
├── dist/
├── hellostackoverflow.egg-info/
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

至此,我们有了一个可以使用安装的软件包pip,因此从我们的项目根目录开始(假设您具有本示例中的所有命名):

pip install ./dist/hellostackoverflow-0.0.1.tar.gz

如果一切顺利,我们现在可以打开一个Python解释器,我想在项目目录之外的某个地方说以避免任何混淆,然后尝试使用新的闪亮包:

Python 3.5.2 (default, Sep 14 2017, 22:51:06) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from hellostackoverflow import hellostackoverflow
>>> hellostackoverflow.greeting()
'Hello Stack Overflow!'

现在,我们已经确认该软件包已安装并且可以正常工作,我们可以将其上传到PyPI。

由于我们不想用我们的实验污染实时存储库,因此我们为测试存储库创建一个帐户,并twine为上载过程进行安装:

pip install twine

现在我们快到了,创建帐户后,我们只需要告诉twine我们上传软件包,它将要求我们提供凭据并将软件包上传到指定的存储库:

twine upload --repository-url https://test.pypi.org/legacy/ dist/*

现在,我们可以在PyPI测试库上登录我们的帐户,惊叹我们刚上传的软件包一段时间,然后使用pip以下代码进行抓取:

pip install --index-url https://test.pypi.org/simple/ hellostackoverflow

我们可以看到,基本过程不是很复杂。正如我之前所说的,它所包含的内容远不止本文所述,因此请继续阅读本教程以获取更深入的说明。

Since nobody did cover this question of the OP yet:

What I wanted to do:

Make a python module install-able with “pip install …”

Here is an absolute minimal example, showing the basic steps of preparing and uploading your package to PyPI using setuptools and twine.

This is by no means a substitute for reading at least the tutorial, there is much more to it than covered in this very basic example.

Creating the package itself is already covered by other answers here, so let us assume we have that step covered and our project structure like this:

.
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

In order to use setuptools for packaging, we need to add a file setup.py, this goes into the root folder of our project:

.
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

At the minimum, we specify the metadata for our package, our setup.py would look like this:

from setuptools import setup

setup(
    name='hellostackoverflow',
    version='0.0.1',
    description='a pip-installable package example',
    license='MIT',
    packages=['hellostackoverflow'],
    author='Benjamin Gerfelder',
    author_email='benjamin.gerfelder@gmail.com',
    keywords=['example'],
    url='https://github.com/bgse/hellostackoverflow'
)

Since we have set license='MIT', we include a copy in our project as LICENCE.txt, alongside a readme file in reStructuredText as README.rst:

.
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

At this point, we are ready to go to start packaging using setuptools, if we do not have it already installed, we can install it with pip:

pip install setuptools

In order to do that and create a source distribution, at our project root folder we call our setup.py from the command line, specifying we want sdist:

python setup.py sdist

This will create our distribution package and egg-info, and result in a folder structure like this, with our package in dist:

.
├── dist/
├── hellostackoverflow.egg-info/
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

At this point, we have a package we can install using pip, so from our project root (assuming you have all the naming like in this example):

pip install ./dist/hellostackoverflow-0.0.1.tar.gz

If all goes well, we can now open a Python interpreter, I would say somewhere outside our project directory to avoid any confusion, and try to use our shiny new package:

Python 3.5.2 (default, Sep 14 2017, 22:51:06) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from hellostackoverflow import hellostackoverflow
>>> hellostackoverflow.greeting()
'Hello Stack Overflow!'

Now that we have confirmed the package installs and works, we can upload it to PyPI.

Since we do not want to pollute the live repository with our experiments, we create an account for the testing repository, and install twine for the upload process:

pip install twine

Now we’re almost there, with our account created we simply tell twine to upload our package, it will ask for our credentials and upload our package to the specified repository:

twine upload --repository-url https://test.pypi.org/legacy/ dist/*

We can now log into our account on the PyPI test repository and marvel at our freshly uploaded package for a while, and then grab it using pip:

pip install --index-url https://test.pypi.org/simple/ hellostackoverflow

As we can see, the basic process is not very complicated. As I said earlier, there is a lot more to it than covered here, so go ahead and read the tutorial for more in-depth explanation.


回答 3

定义所选命令后,只需将保存的文件拖放到python程序文件中的Lib文件夹中即可。

>>> import mymodule 
>>> mymodule.myfunc()

Once you have defined your chosen commands, you can simply drag and drop the saved file into the Lib folder in your python program files.

>>> import mymodule 
>>> mymodule.myfunc()

回答 4

制作一个名为“ hello.py”的文件

如果您使用的是Python 2.x

def func():
    print "Hello"

如果您使用的是Python 3.x

def func():
    print("Hello")

运行文件。然后,您可以尝试以下操作:

>>> import hello
>>> hello.func()
Hello

如果您想稍微努力一点,可以使用以下方法:

如果您使用的是Python 2.x

def say(text):
    print text

如果您使用的是Python 3.x

def say(text):
    print(text)

看到定义旁边括号中的一个吗?那很重要。您可以在定义中使用它。

文本-​​当您希望程序说出想要的内容时可以使用它。根据其名称,它是文本。希望您知道文本的含义。它的意思是“单词”或“句子”。

运行文件。然后,如果您使用的是Python 3.x,则可以尝试以下操作:

>>> import hello
>>> hello.say("hi")
hi
>>> from hello import say
>>> say("test")
test

对于Python 2.x-我猜与Python 3相同吗?不知道。如果我在Python 2.x上犯了一个错误,请纠正我(我知道Python 2,但是我与Python 3一起使用)

Make a file named “hello.py”

If you are using Python 2.x

def func():
    print "Hello"

If you are using Python 3.x

def func():
    print("Hello")

Run the file. Then, you can try the following:

>>> import hello
>>> hello.func()
Hello

If you want a little bit hard, you can use the following:

If you are using Python 2.x

def say(text):
    print text

If you are using Python 3.x

def say(text):
    print(text)

See the one on the parenthesis beside the define? That is important. It is the one that you can use within the define.

Text – You can use it when you want the program to say what you want. According to its name, it is text. I hope you know what text means. It means “words” or “sentences”.

Run the file. Then, you can try the following if you are using Python 3.x:

>>> import hello
>>> hello.say("hi")
hi
>>> from hello import say
>>> say("test")
test

For Python 2.x – I guess same thing with Python 3? No idea. Correct me if I made a mistake on Python 2.x (I know Python 2 but I am used with Python 3)


回答 5

我创建了一个项目,以轻松地从头开始创建项目框架https://github.com/MacHu-GWU/pygitrepo-project

假设您可以创建一个测试项目learn_creating_py_package

您可以了解具有不同用途的组件,例如

  • 创建virtualenv
  • 自行安装
  • 运行单元测试
  • 运行代码覆盖率
  • 建立文件
  • 部署文件
  • 在不同的python版本中运行unittest
  • 部署到PYPI

使用的好处pygitrepo是,这些繁琐的自动创建本身和适应你package_nameproject_namegithub_accountdocument host servicewindows or macos or linux

这是学习像pro一样开发python项目的好地方。

希望这会有所帮助。

谢谢。

I created a project to easily initiate a project skeleton from scratch. https://github.com/MacHu-GWU/pygitrepo-project.

And you can create a test project, let’s say, learn_creating_py_package.

You can learn what component you should have for different purpose like:

  • create virtualenv
  • install itself
  • run unittest
  • run code coverage
  • build document
  • deploy document
  • run unittest in different python version
  • deploy to PYPI

The advantage of using pygitrepo is that those tedious are automatically created itself and adapt your package_name, project_name, github_account, document host service, windows or macos or linux.

It is a good place to learn develop a python project like a pro.

Hope this could help.

Thank you.


如何使用python找出我的python路径?

问题:如何使用python找出我的python路径?

如何PYTHONPATH从Python脚本(或交互式外壳程序)中找出系统变量中列出了哪些目录?

How do I find out which directories are listed in my system’s PYTHONPATH variable, from within a Python script (or the interactive shell)?


回答 0

sys.path可能包括不是您的PYTHONPATH环境变量中特定的项目。要直接查询变量,请使用:

import os
try:
    user_paths = os.environ['PYTHONPATH'].split(os.pathsep)
except KeyError:
    user_paths = []

sys.path might include items that aren’t specifically in your PYTHONPATH environment variable. To query the variable directly, use:

import os
try:
    user_paths = os.environ['PYTHONPATH'].split(os.pathsep)
except KeyError:
    user_paths = []

回答 1

您可能还希望这样:

import sys
print(sys.path)

或者作为从终端的一行代码:

python -c "import sys; print('\n'.join(sys.path))"

注意:如果您安装了多个版本的Python,则应使用相应的命令python2python3

You would probably also want this:

import sys
print(sys.path)

Or as a one liner from the terminal:

python -c "import sys; print('\n'.join(sys.path))"

Caveat: If you have multiple versions of Python installed you should use a corresponding command python2 or python3.


回答 2

似乎无法编辑其他答案。有一个小错误,因为它仅适用于Windows。更通用的解决方案是使用os.sep,如下所示:

sys.path可能包含不是您的PYTHONPATH环境变量中特定的项目。要直接查询变量,请使用:

import os
os.environ['PYTHONPATH'].split(os.pathsep)

Can’t seem to edit the other answer. Has a minor error in that it is Windows-only. The more generic solution is to use os.sep as below:

sys.path might include items that aren’t specifically in your PYTHONPATH environment variable. To query the variable directly, use:

import os
os.environ['PYTHONPATH'].split(os.pathsep)

回答 3

PYTHONPATH是一个环境变量,其值是目录列表。设置后,Python将使用它与其他标准输入一起搜索导入的模块。和Python的“ sys.path”中列出的第三方库目录。

与其他任何环境变量一样,您可以将其导出到shell或〜/ .bashrc中,请参见此处。您可以在python中查询os.environ [‘PYTHONPATH’]的值,如下所示:

$ python3 -c "import os, sys; print(os.environ['PYTHONPATH']); print(sys.path) if 'PYTHONPATH' in sorted(os.environ) else print('PYTHONPATH is not defined')"

如果在shell中将IF定义为

$ export PYTHONPATH=$HOME/Documents/DjangoTutorial/mysite

然后结果=>

/home/Documents/DjangoTutorial/mysite
['', '/home/Documents/DjangoTutorial/mysite', '/usr/local/lib/python37.zip', '/usr/local/lib/python3.7', '/usr/local/lib/python3.7/lib-dynload', '/usr/local/lib/python3.7/site-packages']

ELSE结果=>

PYTHONPATH is not defined

要将PYTHONPATH设置为多个路径,请参见此处

注意,可以在运行时通过sys.path.insert(),del或remove()添加或删除搜索路径,但不能通过os.environ []添加或删除搜索路径。例:

>>> os.environ['PYTHONPATH']="$HOME/Documents/DjangoTutorial/mysite"
>>> 'PYTHONPATH' in sorted(os.environ)
True
>>> sys.path // but Not there
['', '/usr/local/lib/python37.zip', '/usr/local/lib/python3.7', '/usr/local/lib/python3.7/lib-dynload', '/usr/local/lib/python3.7/site-packages']

>>> sys.path.insert(0,os.environ['PYTHONPATH'])
>>> sys.path // It's there
['$HOME/Documents/DjangoTutorial/mysite', '', '/usr/local/lib/python37.zip', '/usr/local/lib/python3.7', '/usr/local/lib/python3.7/lib-dynload', '/usr/local/lib/python3.7/site-packages']
>>> 

总之,PYTHONPATH是在sys.path中为导入的模块指定Python搜索路径的一种方法。您也可以不借助PYTHONPATH将列表操作直接应用于sys.path。

PYTHONPATH is an environment variable whose value is a list of directories. Once set, it is used by Python to search for imported modules, along with other std. and 3rd-party library directories listed in Python’s “sys.path”.

As any other environment variables, you can either export it in shell or in ~/.bashrc, see here. You can query os.environ[‘PYTHONPATH’] for its value in Python as shown below:

$ python3 -c "import os, sys; print(os.environ['PYTHONPATH']); print(sys.path) if 'PYTHONPATH' in sorted(os.environ) else print('PYTHONPATH is not defined')"

IF defined in shell as

$ export PYTHONPATH=$HOME/Documents/DjangoTutorial/mysite

THEN result =>

/home/Documents/DjangoTutorial/mysite
['', '/home/Documents/DjangoTutorial/mysite', '/usr/local/lib/python37.zip', '/usr/local/lib/python3.7', '/usr/local/lib/python3.7/lib-dynload', '/usr/local/lib/python3.7/site-packages']

ELSE result =>

PYTHONPATH is not defined

To set PYTHONPATH to multiple paths, see here.

Note that one can add or delete a search path via sys.path.insert(), del or remove() at run-time, but NOT through os.environ[]. Example:

>>> os.environ['PYTHONPATH']="$HOME/Documents/DjangoTutorial/mysite"
>>> 'PYTHONPATH' in sorted(os.environ)
True
>>> sys.path // but Not there
['', '/usr/local/lib/python37.zip', '/usr/local/lib/python3.7', '/usr/local/lib/python3.7/lib-dynload', '/usr/local/lib/python3.7/site-packages']

>>> sys.path.insert(0,os.environ['PYTHONPATH'])
>>> sys.path // It's there
['$HOME/Documents/DjangoTutorial/mysite', '', '/usr/local/lib/python37.zip', '/usr/local/lib/python3.7', '/usr/local/lib/python3.7/lib-dynload', '/usr/local/lib/python3.7/site-packages']
>>> 

In summary, PYTHONPATH is one way of specifying the Python search path(s) for imported modules in sys.path. You can also apply list operations directly to sys.path without the aid of PYTHONPATH.


回答 4

当它给我一条错误消息时,Python告诉我它住在哪里:)

>>> import os
>>> os.environ['PYTHONPATH'].split(os.pathsep)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\martin\AppData\Local\Programs\Python\Python36-32\lib\os.py", line 669, in __getitem__
    raise KeyError(key) from None
KeyError: 'PYTHONPATH'
>>>

Python tells me where it lives when it gives me an error message :)

>>> import os
>>> os.environ['PYTHONPATH'].split(os.pathsep)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\martin\AppData\Local\Programs\Python\Python36-32\lib\os.py", line 669, in __getitem__
    raise KeyError(key) from None
KeyError: 'PYTHONPATH'
>>>

回答 5

用这个:

import sys
print(sys.executable)

或从cmd一行:

python -c "import sys; print(sys.executable)"

Use this:

import sys
print(sys.executable)

Or one line from the cmd:

python -c "import sys; print(sys.executable)"

如何在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/"

给定完整路径,如何导入模块?

问题:给定完整路径,如何导入模块?

给定完整路径,如何加载Python模块?请注意,该文件可以在文件系统中的任何位置,因为它是配置选项。

How can I load a Python module given its full path? Note that the file can be anywhere in the filesystem, as it is a configuration option.


回答 0

对于Python 3.5+,请使用:

import importlib.util
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
foo.MyClass()

对于Python 3.3和3.4,请使用:

from importlib.machinery import SourceFileLoader

foo = SourceFileLoader("module.name", "/path/to/file.py").load_module()
foo.MyClass()

(尽管在Python 3.4中已弃用此功能。)

对于Python 2,请使用:

import imp

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

编译后的Python文件和DLL具有等效的便捷功能。

另请参见http://bugs.python.org/issue21436

For Python 3.5+ use:

import importlib.util
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
foo.MyClass()

For Python 3.3 and 3.4 use:

from importlib.machinery import SourceFileLoader

foo = SourceFileLoader("module.name", "/path/to/file.py").load_module()
foo.MyClass()

(Although this has been deprecated in Python 3.4.)

For Python 2 use:

import imp

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

There are equivalent convenience functions for compiled Python files and DLLs.

See also http://bugs.python.org/issue21436.


回答 1

(通过使用imp)向sys.path添加路径的好处是,当从单个包中导入多个模块时,它可以简化操作。例如:

import sys
# the mock-0.3.1 dir contains testcase.py, testutils.py & mock.py
sys.path.append('/foo/bar/mock-0.3.1')

from testcase import TestCase
from testutils import RunTests
from mock import Mock, sentinel, patch

The advantage of adding a path to sys.path (over using imp) is that it simplifies things when importing more than one module from a single package. For example:

import sys
# the mock-0.3.1 dir contains testcase.py, testutils.py & mock.py
sys.path.append('/foo/bar/mock-0.3.1')

from testcase import TestCase
from testutils import RunTests
from mock import Mock, sentinel, patch

回答 2

如果您的顶级模块不是文件,而是与__init__.py一起打包为目录,则可接受的解决方案几乎可以使用,但效果不佳。在Python 3.5+中,需要以下代码(请注意,添加的行以’sys.modules’开头):

MODULE_PATH = "/path/to/your/module/__init__.py"
MODULE_NAME = "mymodule"
import importlib
import sys
spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module 
spec.loader.exec_module(module)

如果没有此行,则在执行exec_module时,它将尝试将顶级__init__.py中的相对导入绑定到顶级模块名称(在本例中为“ mymodule”)。但是“ mymodule”尚未加载,因此您将收到错误“ SystemError:父模块’mymodule’未加载,无法执行相对导入”。因此,在加载名称之前,需要先绑定名称。这样做的原因是相对导入系统的基本不变性:“不变性在于,如果您拥有sys.modules [‘spam’]和sys.modules [‘spam.foo’](就像在完成上述导入之后一样) ),后者必须显示为前者的foo属性” ,如此处所述

If your top-level module is not a file but is packaged as a directory with __init__.py, then the accepted solution almost works, but not quite. In Python 3.5+ the following code is needed (note the added line that begins with ‘sys.modules’):

MODULE_PATH = "/path/to/your/module/__init__.py"
MODULE_NAME = "mymodule"
import importlib
import sys
spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module 
spec.loader.exec_module(module)

Without this line, when exec_module is executed, it tries to bind relative imports in your top level __init__.py to the top level module name — in this case “mymodule”. But “mymodule” isn’t loaded yet so you’ll get the error “SystemError: Parent module ‘mymodule’ not loaded, cannot perform relative import”. So you need to bind the name before you load it. The reason for this is the fundamental invariant of the relative import system: “The invariant holding is that if you have sys.modules[‘spam’] and sys.modules[‘spam.foo’] (as you would after the above import), the latter must appear as the foo attribute of the former” as discussed here.


回答 3

要导入模块,您需要将其目录临时或永久地添加到环境变量中。

暂时

import sys
sys.path.append("/path/to/my/modules/")
import my_module

永久性

.bashrc将以下行添加到您的文件(在Linux中)并source ~/.bashrc在终端中执行:

export PYTHONPATH="${PYTHONPATH}:/path/to/my/modules/"

信用/来源:saarrrr另一个stackexchange 问题

To import your module, you need to add its directory to the environment variable, either temporarily or permanently.

Temporarily

import sys
sys.path.append("/path/to/my/modules/")
import my_module

Permanently

Adding the following line to your .bashrc file (in linux) and excecute source ~/.bashrc in the terminal:

export PYTHONPATH="${PYTHONPATH}:/path/to/my/modules/"

Credit/Source: saarrrr, another stackexchange question


回答 4

听起来您似乎不想专门导入配置文件(它具有很多副作用和其他复杂性),您只想运行它并能够访问生成的命名空间。标准库以runpy.run_path的形式专门提供了一个API :

from runpy import run_path
settings = run_path("/path/to/file.py")

该接口在Python 2.7和Python 3.2+中可用

It sounds like you don’t want to specifically import the configuration file (which has a whole lot of side effects and additional complications involved), you just want to run it, and be able to access the resulting namespace. The standard library provides an API specifically for that in the form of runpy.run_path:

from runpy import run_path
settings = run_path("/path/to/file.py")

That interface is available in Python 2.7 and Python 3.2+


回答 5

您还可以执行类似的操作,并将配置文件所在的目录添加到Python加载路径中,然后进行常规导入,前提是您事先知道文件名,在本例中为“ config”。

凌乱,但有效。

configfile = '~/config.py'

import os
import sys

sys.path.append(os.path.dirname(os.path.expanduser(configfile)))

import config

You can also do something like this and add the directory that the configuration file is sitting in to the Python load path, and then just do a normal import, assuming you know the name of the file in advance, in this case “config”.

Messy, but it works.

configfile = '~/config.py'

import os
import sys

sys.path.append(os.path.dirname(os.path.expanduser(configfile)))

import config

回答 6

您可以使用

load_source(module_name, path_to_file) 

来自imp模块的方法。

You can use the

load_source(module_name, path_to_file) 

method from imp module.


回答 7

def import_file(full_path_to_module):
    try:
        import os
        module_dir, module_file = os.path.split(full_path_to_module)
        module_name, module_ext = os.path.splitext(module_file)
        save_cwd = os.getcwd()
        os.chdir(module_dir)
        module_obj = __import__(module_name)
        module_obj.__file__ = full_path_to_module
        globals()[module_name] = module_obj
        os.chdir(save_cwd)
    except:
        raise ImportError

import_file('/home/somebody/somemodule.py')
def import_file(full_path_to_module):
    try:
        import os
        module_dir, module_file = os.path.split(full_path_to_module)
        module_name, module_ext = os.path.splitext(module_file)
        save_cwd = os.getcwd()
        os.chdir(module_dir)
        module_obj = __import__(module_name)
        module_obj.__file__ = full_path_to_module
        globals()[module_name] = module_obj
        os.chdir(save_cwd)
    except:
        raise ImportError

import_file('/home/somebody/somemodule.py')

回答 8

这是一些适用于所有Python版本(从2.7-3.5,甚至其他版本)的代码。

config_file = "/tmp/config.py"
with open(config_file) as f:
    code = compile(f.read(), config_file, 'exec')
    exec(code, globals(), locals())

我测试了 它可能很丑陋,但到目前为止,它是唯一可以在所有版本中使用的版本。

Here is some code that works in all Python versions, from 2.7-3.5 and probably even others.

config_file = "/tmp/config.py"
with open(config_file) as f:
    code = compile(f.read(), config_file, 'exec')
    exec(code, globals(), locals())

I tested it. It may be ugly but so far is the only one that works in all versions.


回答 9

我想出了@SebastianRittau的一个很好的答案的略微修改的版本(我认为是针对Python> 3.4),它允许您使用spec_from_loader而不是使用模块将具有任何扩展名的文件加载为模块spec_from_file_location

from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader 

spec = spec_from_loader("module.name", SourceFileLoader("module.name", "/path/to/file.py"))
mod = module_from_spec(spec)
spec.loader.exec_module(mod)

以显式SourceFileLoader方式对路径进行编码的优点在于,该机制不会尝试从扩展名中找出文件的类型。这意味着您可以.txt使用此方法加载类似文件的内容,但是如果spec_from_file_location不指定loader,.txt则无法进行加载,因为not in中importlib.machinery.SOURCE_SUFFIXES

I have come up with a slightly modified version of @SebastianRittau’s wonderful answer (for Python > 3.4 I think), which will allow you to load a file with any extension as a module using spec_from_loader instead of spec_from_file_location:

from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader 

spec = spec_from_loader("module.name", SourceFileLoader("module.name", "/path/to/file.py"))
mod = module_from_spec(spec)
spec.loader.exec_module(mod)

The advantage of encoding the path in an explicit SourceFileLoader is that the machinery will not try to figure out the type of the file from the extension. This means that you can load something like a .txt file using this method, but you could not do it with spec_from_file_location without specifying the loader because .txt is not in importlib.machinery.SOURCE_SUFFIXES.


回答 10

您是指加载还是导入?

您可以操纵sys.path列表,指定模块的路径,然后导入模块。例如,给定一个模块位于:

/foo/bar.py

您可以这样做:

import sys
sys.path[0:0] = ['/foo'] # puts the /foo directory at the start of your path
import bar

Do you mean load or import?

You can manipulate the sys.path list specify the path to your module, then import your module. For example, given a module at:

/foo/bar.py

You could do:

import sys
sys.path[0:0] = ['/foo'] # puts the /foo directory at the start of your path
import bar

回答 11

我相信你可以使用imp.find_module()imp.load_module()加载指定的模块。您需要从路径中拆分模块名称,即,如果要加载/home/mypath/mymodule.py,则需要执行以下操作:

imp.find_module('mymodule', '/home/mypath/')

…但这应该可以完成工作。

I believe you can use imp.find_module() and imp.load_module() to load the specified module. You’ll need to split the module name off of the path, i.e. if you wanted to load /home/mypath/mymodule.py you’d need to do:

imp.find_module('mymodule', '/home/mypath/')

…but that should get the job done.


回答 12

您可以使用pkgutil模块(特别是walk_packages方法)来获取当前目录中软件包的列表。从那里开始,使用importlib机器导入所需的模块很简单:

import pkgutil
import importlib

packages = pkgutil.walk_packages(path='.')
for importer, name, is_package in packages:
    mod = importlib.import_module(name)
    # do whatever you want with module now, it's been imported!

You can use the pkgutil module (specifically the walk_packages method) to get a list of the packages in the current directory. From there it’s trivial to use the importlib machinery to import the modules you want:

import pkgutil
import importlib

packages = pkgutil.walk_packages(path='.')
for importer, name, is_package in packages:
    mod = importlib.import_module(name)
    # do whatever you want with module now, it's been imported!

回答 13

创建python模块test.py

import sys
sys.path.append("<project-path>/lib/")
from tes1 import Client1
from tes2 import Client2
import tes3

创建python模块test_check.py

from test import Client1
from test import Client2
from test import test3

我们可以从模块导入导入的模块。

Create python module test.py

import sys
sys.path.append("<project-path>/lib/")
from tes1 import Client1
from tes2 import Client2
import tes3

Create python module test_check.py

from test import Client1
from test import Client2
from test import test3

We can import the imported module from module.


回答 14

Python 3.4的这一领域似乎很难理解!但是,通过使用Chris Calloway的代码进行了一些黑客操作,我设法使某些东西起作用。这是基本功能。

def import_module_from_file(full_path_to_module):
    """
    Import a module given the full path/filename of the .py file

    Python 3.4

    """

    module = None

    try:

        # Get module name and path from full path
        module_dir, module_file = os.path.split(full_path_to_module)
        module_name, module_ext = os.path.splitext(module_file)

        # Get module "spec" from filename
        spec = importlib.util.spec_from_file_location(module_name,full_path_to_module)

        module = spec.loader.load_module()

    except Exception as ec:
        # Simple error printing
        # Insert "sophisticated" stuff here
        print(ec)

    finally:
        return module

这似乎使用了Python 3.4中不推荐使用的模块。我不假装理解为什么,但是它似乎可以在程序中运行。我发现克里斯的解决方案在命令行上有效,但不是在程序内部。

This area of Python 3.4 seems to be extremely tortuous to understand! However with a bit of hacking using the code from Chris Calloway as a start I managed to get something working. Here’s the basic function.

def import_module_from_file(full_path_to_module):
    """
    Import a module given the full path/filename of the .py file

    Python 3.4

    """

    module = None

    try:

        # Get module name and path from full path
        module_dir, module_file = os.path.split(full_path_to_module)
        module_name, module_ext = os.path.splitext(module_file)

        # Get module "spec" from filename
        spec = importlib.util.spec_from_file_location(module_name,full_path_to_module)

        module = spec.loader.load_module()

    except Exception as ec:
        # Simple error printing
        # Insert "sophisticated" stuff here
        print(ec)

    finally:
        return module

This appears to use non-deprecated modules from Python 3.4. I don’t pretend to understand why, but it seems to work from within a program. I found Chris’ solution worked on the command line but not from inside a program.


回答 15

我并不是说它更好,但是为了完整起见,我想建议该exec函数在python 2和3中都可用。 exec提供允许您在全局范围或内部范围内执行任意代码,作为字典提供。

例如,如果您"/path/to/module的函数中存储有一个模块,则foo()可以执行以下操作:

module = dict()
with open("/path/to/module") as f:
    exec(f.read(), module)
module['foo']()

这使您可以动态加载代码更加明确,并赋予您一些额外的功能,例如提供自定义内置函数的能力。

如果通过属性(而不是键)进行访问对您很重要,则可以为全局对象设计一个自定义dict类,它提供了这种访问,例如:

class MyModuleClass(dict):
    def __getattr__(self, name):
        return self.__getitem__(name)

I’m not saying that it is better, but for the sake of completeness, I wanted to suggest the exec function, available in both python 2 and 3. exec allows you to execute arbitrary code in either the global scope, or in an internal scope, provided as a dictionary.

For example, if you have a module stored in "/path/to/module” with the function foo(), you could run it by doing the following:

module = dict()
with open("/path/to/module") as f:
    exec(f.read(), module)
module['foo']()

This makes it a bit more explicit that you’re loading code dynamically, and grants you some additional power, such as the ability to provide custom builtins.

And if having access through attributes, instead of keys is important to you, you can design a custom dict class for the globals, that provides such access, e.g.:

class MyModuleClass(dict):
    def __getattr__(self, name):
        return self.__getitem__(name)

回答 16

要从给定的文件名导入模块,可以临时扩展路径,并在finally块引用中恢复系统路径

filename = "directory/module.py"

directory, module_name = os.path.split(filename)
module_name = os.path.splitext(module_name)[0]

path = list(sys.path)
sys.path.insert(0, directory)
try:
    module = __import__(module_name)
finally:
    sys.path[:] = path # restore

To import a module from a given filename, you can temporarily extend the path, and restore the system path in the finally block reference:

filename = "directory/module.py"

directory, module_name = os.path.split(filename)
module_name = os.path.splitext(module_name)[0]

path = list(sys.path)
sys.path.insert(0, directory)
try:
    module = __import__(module_name)
finally:
    sys.path[:] = path # restore

回答 17

这应该工作

path = os.path.join('./path/to/folder/with/py/files', '*.py')
for infile in glob.glob(path):
    basename = os.path.basename(infile)
    basename_without_extension = basename[:-3]

    # http://docs.python.org/library/imp.html?highlight=imp#module-imp
    imp.load_source(basename_without_extension, infile)

This should work

path = os.path.join('./path/to/folder/with/py/files', '*.py')
for infile in glob.glob(path):
    basename = os.path.basename(infile)
    basename_without_extension = basename[:-3]

    # http://docs.python.org/library/imp.html?highlight=imp#module-imp
    imp.load_source(basename_without_extension, infile)

回答 18

如果我们在同一项目中有脚本,但在不同的目录中有脚本,则可以通过以下方法解决此问题。

在这种情况下utils.pysrc/main/util/

import sys
sys.path.append('./')

import src.main.util.utils
#or
from src.main.util.utils import json_converter # json_converter is example method

If we have scripts in the same project but in different directory means, we can solve this problem by the following method.

In this situation utils.py is in src/main/util/

import sys
sys.path.append('./')

import src.main.util.utils
#or
from src.main.util.utils import json_converter # json_converter is example method

回答 19

imp为您准备了一个包装。我称呼它import_file,这就是它的用法:

>>>from import_file import import_file
>>>mylib = import_file('c:\\mylib.py')
>>>another = import_file('relative_subdir/another.py')

您可以在以下位置获得它:

http://pypi.python.org/pypi/import_file

http://code.google.com/p/import-file/

I made a package that uses imp for you. I call it import_file and this is how it’s used:

>>>from import_file import import_file
>>>mylib = import_file('c:\\mylib.py')
>>>another = import_file('relative_subdir/another.py')

You can get it at:

http://pypi.python.org/pypi/import_file

or at

http://code.google.com/p/import-file/


回答 20

在运行时导入软件包模块(Python配方)

http://code.activestate.com/recipes/223972/

###################
##                #
## classloader.py #
##                #
###################

import sys, types

def _get_mod(modulePath):
    try:
        aMod = sys.modules[modulePath]
        if not isinstance(aMod, types.ModuleType):
            raise KeyError
    except KeyError:
        # The last [''] is very important!
        aMod = __import__(modulePath, globals(), locals(), [''])
        sys.modules[modulePath] = aMod
    return aMod

def _get_func(fullFuncName):
    """Retrieve a function object from a full dotted-package name."""

    # Parse out the path, module, and function
    lastDot = fullFuncName.rfind(u".")
    funcName = fullFuncName[lastDot + 1:]
    modPath = fullFuncName[:lastDot]

    aMod = _get_mod(modPath)
    aFunc = getattr(aMod, funcName)

    # Assert that the function is a *callable* attribute.
    assert callable(aFunc), u"%s is not callable." % fullFuncName

    # Return a reference to the function itself,
    # not the results of the function.
    return aFunc

def _get_class(fullClassName, parentClass=None):
    """Load a module and retrieve a class (NOT an instance).

    If the parentClass is supplied, className must be of parentClass
    or a subclass of parentClass (or None is returned).
    """
    aClass = _get_func(fullClassName)

    # Assert that the class is a subclass of parentClass.
    if parentClass is not None:
        if not issubclass(aClass, parentClass):
            raise TypeError(u"%s is not a subclass of %s" %
                            (fullClassName, parentClass))

    # Return a reference to the class itself, not an instantiated object.
    return aClass


######################
##       Usage      ##
######################

class StorageManager: pass
class StorageManagerMySQL(StorageManager): pass

def storage_object(aFullClassName, allOptions={}):
    aStoreClass = _get_class(aFullClassName, StorageManager)
    return aStoreClass(allOptions)

Import package modules at runtime (Python recipe)

http://code.activestate.com/recipes/223972/

###################
##                #
## classloader.py #
##                #
###################

import sys, types

def _get_mod(modulePath):
    try:
        aMod = sys.modules[modulePath]
        if not isinstance(aMod, types.ModuleType):
            raise KeyError
    except KeyError:
        # The last [''] is very important!
        aMod = __import__(modulePath, globals(), locals(), [''])
        sys.modules[modulePath] = aMod
    return aMod

def _get_func(fullFuncName):
    """Retrieve a function object from a full dotted-package name."""

    # Parse out the path, module, and function
    lastDot = fullFuncName.rfind(u".")
    funcName = fullFuncName[lastDot + 1:]
    modPath = fullFuncName[:lastDot]

    aMod = _get_mod(modPath)
    aFunc = getattr(aMod, funcName)

    # Assert that the function is a *callable* attribute.
    assert callable(aFunc), u"%s is not callable." % fullFuncName

    # Return a reference to the function itself,
    # not the results of the function.
    return aFunc

def _get_class(fullClassName, parentClass=None):
    """Load a module and retrieve a class (NOT an instance).

    If the parentClass is supplied, className must be of parentClass
    or a subclass of parentClass (or None is returned).
    """
    aClass = _get_func(fullClassName)

    # Assert that the class is a subclass of parentClass.
    if parentClass is not None:
        if not issubclass(aClass, parentClass):
            raise TypeError(u"%s is not a subclass of %s" %
                            (fullClassName, parentClass))

    # Return a reference to the class itself, not an instantiated object.
    return aClass


######################
##       Usage      ##
######################

class StorageManager: pass
class StorageManagerMySQL(StorageManager): pass

def storage_object(aFullClassName, allOptions={}):
    aStoreClass = _get_class(aFullClassName, StorageManager)
    return aStoreClass(allOptions)

回答 21

在Linux中,可以在python脚本所在的目录中添加符号链接。

即:

ln -s /absolute/path/to/module/module.py /absolute/path/to/script/module.py

/absolute/path/to/script/module.pyc如果您更改python 的内容,python将会创建并更新它/absolute/path/to/module/module.py

然后在mypythonscript.py中包含以下内容

from module import *

In Linux, adding a symbolic link in the directory your python script is located works.

ie:

ln -s /absolute/path/to/module/module.py /absolute/path/to/script/module.py

python will create /absolute/path/to/script/module.pyc and will update it if you change the contents of /absolute/path/to/module/module.py

then include the following in mypythonscript.py

from module import *

回答 22

我已经基于importlib模块编写了自己的全局和可移植导入函数,用于:

  • 既可以将两个模块都作为子模块导入,又可以将模块的内容导入父模块(如果没有父模块,则可以导入全局变量)。
  • 能够导入文件名中带有句点字符的模块。
  • 能够导入具有任何扩展名的模块。
  • 能够为子模块使用独立名称,而不是默认情况下不带扩展名的文件名。
  • 能够基于先前导入的模块来定义导入顺序,而不是依赖于sys.path或依赖于什么搜索路径存储。

示例目录结构:

<root>
 |
 +- test.py
 |
 +- testlib.py
 |
 +- /std1
 |   |
 |   +- testlib.std1.py
 |
 +- /std2
 |   |
 |   +- testlib.std2.py
 |
 +- /std3
     |
     +- testlib.std3.py

包含关系和顺序:

test.py
  -> testlib.py
    -> testlib.std1.py
      -> testlib.std2.py
    -> testlib.std3.py 

实现方式:

最新更改存储:https : //sourceforge.net/p/tacklelib/tacklelib/HEAD/tree/trunk/python/tacklelib/tacklelib.py

test.py

import os, sys, inspect, copy

SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("test::SOURCE_FILE: ", SOURCE_FILE)

# portable import to the global space
sys.path.append(TACKLELIB_ROOT) # TACKLELIB_ROOT - path to the library directory
import tacklelib as tkl

tkl.tkl_init(tkl)

# cleanup
del tkl # must be instead of `tkl = None`, otherwise the variable would be still persist
sys.path.pop()

tkl_import_module(SOURCE_DIR, 'testlib.py')

print(globals().keys())

testlib.base_test()
testlib.testlib_std1.std1_test()
testlib.testlib_std1.testlib_std2.std2_test()
#testlib.testlib.std3.std3_test()                             # does not reachable directly ...
getattr(globals()['testlib'], 'testlib.std3').std3_test()     # ... but reachable through the `globals` + `getattr`

tkl_import_module(SOURCE_DIR, 'testlib.py', '.')

print(globals().keys())

base_test()
testlib_std1.std1_test()
testlib_std1.testlib_std2.std2_test()
#testlib.std3.std3_test()                                     # does not reachable directly ...
globals()['testlib.std3'].std3_test()                         # ... but reachable through the `globals` + `getattr`

testlib.py

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("1 testlib::SOURCE_FILE: ", SOURCE_FILE)

tkl_import_module(SOURCE_DIR + '/std1', 'testlib.std1.py', 'testlib_std1')

# SOURCE_DIR is restored here
print("2 testlib::SOURCE_FILE: ", SOURCE_FILE)

tkl_import_module(SOURCE_DIR + '/std3', 'testlib.std3.py')

print("3 testlib::SOURCE_FILE: ", SOURCE_FILE)

def base_test():
  print('base_test')

testlib.std1.py

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("testlib.std1::SOURCE_FILE: ", SOURCE_FILE)

tkl_import_module(SOURCE_DIR + '/../std2', 'testlib.std2.py', 'testlib_std2')

def std1_test():
  print('std1_test')

testlib.std2.py

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("testlib.std2::SOURCE_FILE: ", SOURCE_FILE)

def std2_test():
  print('std2_test')

testlib.std3.py

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("testlib.std3::SOURCE_FILE: ", SOURCE_FILE)

def std3_test():
  print('std3_test')

输出3.7.4):

test::SOURCE_FILE:  <root>/test01/test.py
import : <root>/test01/testlib.py as testlib -> []
1 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std1/testlib.std1.py as testlib_std1 -> ['testlib']
import : <root>/test01/std1/../std2/testlib.std2.py as testlib_std2 -> ['testlib', 'testlib_std1']
testlib.std2::SOURCE_FILE:  <root>/test01/std1/../std2/testlib.std2.py
2 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std3/testlib.std3.py as testlib.std3 -> ['testlib']
testlib.std3::SOURCE_FILE:  <root>/test01/std3/testlib.std3.py
3 testlib::SOURCE_FILE:  <root>/test01/testlib.py
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'os', 'sys', 'inspect', 'copy', 'SOURCE_FILE', 'SOURCE_DIR', 'TackleGlobalImportModuleState', 'tkl_membercopy', 'tkl_merge_module', 'tkl_get_parent_imported_module_state', 'tkl_declare_global', 'tkl_import_module', 'TackleSourceModuleState', 'tkl_source_module', 'TackleLocalImportModuleState', 'testlib'])
base_test
std1_test
std2_test
std3_test
import : <root>/test01/testlib.py as . -> []
1 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std1/testlib.std1.py as testlib_std1 -> ['testlib']
import : <root>/test01/std1/../std2/testlib.std2.py as testlib_std2 -> ['testlib', 'testlib_std1']
testlib.std2::SOURCE_FILE:  <root>/test01/std1/../std2/testlib.std2.py
2 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std3/testlib.std3.py as testlib.std3 -> ['testlib']
testlib.std3::SOURCE_FILE:  <root>/test01/std3/testlib.std3.py
3 testlib::SOURCE_FILE:  <root>/test01/testlib.py
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'os', 'sys', 'inspect', 'copy', 'SOURCE_FILE', 'SOURCE_DIR', 'TackleGlobalImportModuleState', 'tkl_membercopy', 'tkl_merge_module', 'tkl_get_parent_imported_module_state', 'tkl_declare_global', 'tkl_import_module', 'TackleSourceModuleState', 'tkl_source_module', 'TackleLocalImportModuleState', 'testlib', 'testlib_std1', 'testlib.std3', 'base_test'])
base_test
std1_test
std2_test
std3_test

经测试在Python 3.7.43.2.52.7.16

优点

  • 可以将两个模块都作为子模块导入,也可以将模块的内容导入父模块(如果没有父模块,则可以导入全局变量)。
  • 可以导入文件名中带有句点的模块。
  • 可以从任何扩展模块导入任何扩展模块。
  • 可以为子模块使用独立名称,而不是默认情况下不带扩展名的文件名(例如,testlib.std.pyas testlibtestlib.blabla.pyas testlib_blabla等)。
  • 不依赖于sys.path搜索路径存储。
  • 不需要在调用之间SOURCE_FILESOURCE_DIR之间保存/恢复全局变量tkl_import_module
  • [用于3.4.x和较高]可以混合在嵌套的模块命名空间tkl_import_module的呼叫(例如:named->local->namedlocal->named->local此类推)。
  • [ 3.4.x及更高]可以将全局变量/函数/类从声明的位置自动导出到通过tkl_import_module(通过tkl_declare_global函数)导入的所有子模块。

缺点

  • [for 3.3.xand lower]要求tkl_import_module在所有要调用的模块中声明tkl_import_module(代码重复)

更新1,2(对于3.4.x仅限更高版本):

在Python 3.4及更高版本中,您可以tkl_import_module通过tkl_import_module在顶级模块中进行声明来绕过在每个模块中声明的要求,并且该函数将在一次调用中将自身注入所有子模块(这是一种自我部署导入)。

更新3

添加了tkl_source_module与bash类似的功能,source并在导入时提供了支持执行保护(通过模块合并而不是导入实现)。

更新4

添加tkl_declare_global了将模块全局变量自动导出到所有子模块的功能,这些模块由于不属于子模块而无法看到模块全局变量。

更新5

所有功能都已移入铲斗库,请参见上面的链接。

I have wrote my own global and portable import function, based on importlib module, for:

  • Be able to import both module as a submodule and to import content of a module to a parent module (or into a globals if has no parent module).
  • Be able to import modules with a period characters in a file name.
  • Be able to import modules with any extension.
  • Be able to use a standalone name for a submodule instead of a file name without extension which is by default.
  • Be able to define the import order based on previously imported module instead of dependent on sys.path or on a what ever search path storage.

The examples directory structure:

<root>
 |
 +- test.py
 |
 +- testlib.py
 |
 +- /std1
 |   |
 |   +- testlib.std1.py
 |
 +- /std2
 |   |
 |   +- testlib.std2.py
 |
 +- /std3
     |
     +- testlib.std3.py

Inclusion dependency and order:

test.py
  -> testlib.py
    -> testlib.std1.py
      -> testlib.std2.py
    -> testlib.std3.py 

Implementation:

Latest changes store: https://sourceforge.net/p/tacklelib/tacklelib/HEAD/tree/trunk/python/tacklelib/tacklelib.py

test.py:

import os, sys, inspect, copy

SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("test::SOURCE_FILE: ", SOURCE_FILE)

# portable import to the global space
sys.path.append(TACKLELIB_ROOT) # TACKLELIB_ROOT - path to the library directory
import tacklelib as tkl

tkl.tkl_init(tkl)

# cleanup
del tkl # must be instead of `tkl = None`, otherwise the variable would be still persist
sys.path.pop()

tkl_import_module(SOURCE_DIR, 'testlib.py')

print(globals().keys())

testlib.base_test()
testlib.testlib_std1.std1_test()
testlib.testlib_std1.testlib_std2.std2_test()
#testlib.testlib.std3.std3_test()                             # does not reachable directly ...
getattr(globals()['testlib'], 'testlib.std3').std3_test()     # ... but reachable through the `globals` + `getattr`

tkl_import_module(SOURCE_DIR, 'testlib.py', '.')

print(globals().keys())

base_test()
testlib_std1.std1_test()
testlib_std1.testlib_std2.std2_test()
#testlib.std3.std3_test()                                     # does not reachable directly ...
globals()['testlib.std3'].std3_test()                         # ... but reachable through the `globals` + `getattr`

testlib.py:

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("1 testlib::SOURCE_FILE: ", SOURCE_FILE)

tkl_import_module(SOURCE_DIR + '/std1', 'testlib.std1.py', 'testlib_std1')

# SOURCE_DIR is restored here
print("2 testlib::SOURCE_FILE: ", SOURCE_FILE)

tkl_import_module(SOURCE_DIR + '/std3', 'testlib.std3.py')

print("3 testlib::SOURCE_FILE: ", SOURCE_FILE)

def base_test():
  print('base_test')

testlib.std1.py:

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("testlib.std1::SOURCE_FILE: ", SOURCE_FILE)

tkl_import_module(SOURCE_DIR + '/../std2', 'testlib.std2.py', 'testlib_std2')

def std1_test():
  print('std1_test')

testlib.std2.py:

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("testlib.std2::SOURCE_FILE: ", SOURCE_FILE)

def std2_test():
  print('std2_test')

testlib.std3.py:

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("testlib.std3::SOURCE_FILE: ", SOURCE_FILE)

def std3_test():
  print('std3_test')

Output (3.7.4):

test::SOURCE_FILE:  <root>/test01/test.py
import : <root>/test01/testlib.py as testlib -> []
1 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std1/testlib.std1.py as testlib_std1 -> ['testlib']
import : <root>/test01/std1/../std2/testlib.std2.py as testlib_std2 -> ['testlib', 'testlib_std1']
testlib.std2::SOURCE_FILE:  <root>/test01/std1/../std2/testlib.std2.py
2 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std3/testlib.std3.py as testlib.std3 -> ['testlib']
testlib.std3::SOURCE_FILE:  <root>/test01/std3/testlib.std3.py
3 testlib::SOURCE_FILE:  <root>/test01/testlib.py
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'os', 'sys', 'inspect', 'copy', 'SOURCE_FILE', 'SOURCE_DIR', 'TackleGlobalImportModuleState', 'tkl_membercopy', 'tkl_merge_module', 'tkl_get_parent_imported_module_state', 'tkl_declare_global', 'tkl_import_module', 'TackleSourceModuleState', 'tkl_source_module', 'TackleLocalImportModuleState', 'testlib'])
base_test
std1_test
std2_test
std3_test
import : <root>/test01/testlib.py as . -> []
1 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std1/testlib.std1.py as testlib_std1 -> ['testlib']
import : <root>/test01/std1/../std2/testlib.std2.py as testlib_std2 -> ['testlib', 'testlib_std1']
testlib.std2::SOURCE_FILE:  <root>/test01/std1/../std2/testlib.std2.py
2 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std3/testlib.std3.py as testlib.std3 -> ['testlib']
testlib.std3::SOURCE_FILE:  <root>/test01/std3/testlib.std3.py
3 testlib::SOURCE_FILE:  <root>/test01/testlib.py
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'os', 'sys', 'inspect', 'copy', 'SOURCE_FILE', 'SOURCE_DIR', 'TackleGlobalImportModuleState', 'tkl_membercopy', 'tkl_merge_module', 'tkl_get_parent_imported_module_state', 'tkl_declare_global', 'tkl_import_module', 'TackleSourceModuleState', 'tkl_source_module', 'TackleLocalImportModuleState', 'testlib', 'testlib_std1', 'testlib.std3', 'base_test'])
base_test
std1_test
std2_test
std3_test

Tested in Python 3.7.4, 3.2.5, 2.7.16

Pros:

  • Can import both module as a submodule and can import content of a module to a parent module (or into a globals if has no parent module).
  • Can import modules with periods in a file name.
  • Can import any extension module from any extension module.
  • Can use a standalone name for a submodule instead of a file name without extension which is by default (for example, testlib.std.py as testlib, testlib.blabla.py as testlib_blabla and so on).
  • Does not depend on a sys.path or on a what ever search path storage.
  • Does not require to save/restore global variables like SOURCE_FILE and SOURCE_DIR between calls to tkl_import_module.
  • [for 3.4.x and higher] Can mix the module namespaces in nested tkl_import_module calls (ex: named->local->named or local->named->local and so on).
  • [for 3.4.x and higher] Can auto export global variables/functions/classes from where being declared to all children modules imported through the tkl_import_module (through the tkl_declare_global function).

Cons:

  • [for 3.3.x and lower] Require to declare tkl_import_module in all modules which calls to tkl_import_module (code duplication)

Update 1,2 (for 3.4.x and higher only):

In Python 3.4 and higher you can bypass the requirement to declare tkl_import_module in each module by declare tkl_import_module in a top level module and the function would inject itself to all children modules in a single call (it’s a kind of self deploy import).

Update 3:

Added function tkl_source_module as analog to bash source with support execution guard upon import (implemented through the module merge instead of import).

Update 4:

Added function tkl_declare_global to auto export a module global variable to all children modules where a module global variable is not visible because is not a part of a child module.

Update 5:

All functions has moved into the tacklelib library, see the link above.


回答 23

有一个专用于此的软件包

from thesmuggler import smuggle

# À la `import weapons`
weapons = smuggle('weapons.py')

# À la `from contraband import drugs, alcohol`
drugs, alcohol = smuggle('drugs', 'alcohol', source='contraband.py')

# À la `from contraband import drugs as dope, alcohol as booze`
dope, booze = smuggle('drugs', 'alcohol', source='contraband.py')

它已经在Python版本(也包括Jython和PyPy)上进行了测试,但是根据项目的大小,它可能会显得过大。

There’s a package that’s dedicated to this specifically:

from thesmuggler import smuggle

# À la `import weapons`
weapons = smuggle('weapons.py')

# À la `from contraband import drugs, alcohol`
drugs, alcohol = smuggle('drugs', 'alcohol', source='contraband.py')

# À la `from contraband import drugs as dope, alcohol as booze`
dope, booze = smuggle('drugs', 'alcohol', source='contraband.py')

It’s tested across Python versions (Jython and PyPy too), but it might be overkill depending on the size of your project.


回答 24

将其添加到答案列表中,因为我找不到任何有效的方法。这将允许导入3.4中的已编译(pyd)python模块:

import sys
import importlib.machinery

def load_module(name, filename):
    # If the Loader finds the module name in this list it will use
    # module_name.__file__ instead so we need to delete it here
    if name in sys.modules:
        del sys.modules[name]
    loader = importlib.machinery.ExtensionFileLoader(name, filename)
    module = loader.load_module()
    locals()[name] = module
    globals()[name] = module

load_module('something', r'C:\Path\To\something.pyd')
something.do_something()

Adding this to the list of answers as I couldn’t find anything that worked. This will allow imports of compiled (pyd) python modules in 3.4:

import sys
import importlib.machinery

def load_module(name, filename):
    # If the Loader finds the module name in this list it will use
    # module_name.__file__ instead so we need to delete it here
    if name in sys.modules:
        del sys.modules[name]
    loader = importlib.machinery.ExtensionFileLoader(name, filename)
    module = loader.load_module()
    locals()[name] = module
    globals()[name] = module

load_module('something', r'C:\Path\To\something.pyd')
something.do_something()

回答 25

很简单的方法:假设您要导入具有相对路径../../MyLibs/pyfunc.py的文件


libPath = '../../MyLibs'
import sys
if not libPath in sys.path: sys.path.append(libPath)
import pyfunc as pf

但是,如果没有警卫就可以做到,那么您最终可以走很长的路

quite simple way: suppose you want import file with relative path ../../MyLibs/pyfunc.py


libPath = '../../MyLibs'
import sys
if not libPath in sys.path: sys.path.append(libPath)
import pyfunc as pf

But if you make it without a guard you can finally get a very long path


回答 26

一个简单的解决方案,importlib而不是使用imp包(已针对Python 2.7进行了测试,尽管它也适用于Python 3):

import importlib

dirname, basename = os.path.split(pyfilepath) # pyfilepath: '/my/path/mymodule.py'
sys.path.append(dirname) # only directories should be added to PYTHONPATH
module_name = os.path.splitext(basename)[0] # '/my/path/mymodule.py' --> 'mymodule'
module = importlib.import_module(module_name) # name space of defined module (otherwise we would literally look for "module_name")

现在,您可以直接使用导入模块的命名空间,如下所示:

a = module.myvar
b = module.myfunc(a)

该解决方案的优势在于,为了在我们的代码中使用它,我们甚至不需要知道我们想要导入的模块的实际名称。例如,在模块的路径是可配置参数的情况下,这很有用。

A simple solution using importlib instead of the imp package (tested for Python 2.7, although it should work for Python 3 too):

import importlib

dirname, basename = os.path.split(pyfilepath) # pyfilepath: '/my/path/mymodule.py'
sys.path.append(dirname) # only directories should be added to PYTHONPATH
module_name = os.path.splitext(basename)[0] # '/my/path/mymodule.py' --> 'mymodule'
module = importlib.import_module(module_name) # name space of defined module (otherwise we would literally look for "module_name")

Now you can directly use the namespace of the imported module, like this:

a = module.myvar
b = module.myfunc(a)

The advantage of this solution is that we don’t even need to know the actual name of the module we would like to import, in order to use it in our code. This is useful, e.g. in case the path of the module is a configurable argument.


回答 27

这个答案是塞巴斯蒂安·里陶(Sebastian Rittau)对评论的回答的补充:“但是,如果您没有模块名怎么办?” 这是一种在给定文件名的情况下获取可能的python模块名称的快速而肮脏的方法-它只是沿树走,直到找到没有__init__.py文件的目录,然后将其转换回文件名。对于Python 3.4+(使用pathlib),这很有意义,因为Py2人可以使用“ imp”或其他方式进行相对导入:

import pathlib

def likely_python_module(filename):
    '''
    Given a filename or Path, return the "likely" python module name.  That is, iterate
    the parent directories until it doesn't contain an __init__.py file.

    :rtype: str
    '''
    p = pathlib.Path(filename).resolve()
    paths = []
    if p.name != '__init__.py':
        paths.append(p.stem)
    while True:
        p = p.parent
        if not p:
            break
        if not p.is_dir():
            break

        inits = [f for f in p.iterdir() if f.name == '__init__.py']
        if not inits:
            break

        paths.append(p.stem)

    return '.'.join(reversed(paths))

当然存在改进的可能性,并且可选__init__.py文件可能需要进行其他更改,但是如果__init__.py总的来说,这可以解决问题。

This answer is a supplement to Sebastian Rittau’s answer responding to the comment: “but what if you don’t have the module name?” This is a quick and dirty way of getting the likely python module name given a filename — it just goes up the tree until it finds a directory without an __init__.py file and then turns it back into a filename. For Python 3.4+ (uses pathlib), which makes sense since Py2 people can use “imp” or other ways of doing relative imports:

import pathlib

def likely_python_module(filename):
    '''
    Given a filename or Path, return the "likely" python module name.  That is, iterate
    the parent directories until it doesn't contain an __init__.py file.

    :rtype: str
    '''
    p = pathlib.Path(filename).resolve()
    paths = []
    if p.name != '__init__.py':
        paths.append(p.stem)
    while True:
        p = p.parent
        if not p:
            break
        if not p.is_dir():
            break

        inits = [f for f in p.iterdir() if f.name == '__init__.py']
        if not inits:
            break

        paths.append(p.stem)

    return '.'.join(reversed(paths))

There are certainly possibilities for improvement, and the optional __init__.py files might necessitate other changes, but if you have __init__.py in general, this does the trick.


回答 28

我认为,最好的方法是从官方文档中获取(29.1。imp —访问import internals):

import imp
import sys

def __import__(name, globals=None, locals=None, fromlist=None):
    # Fast path: see if the module has already been imported.
    try:
        return sys.modules[name]
    except KeyError:
        pass

    # If any of the following calls raises an exception,
    # there's a problem we can't handle -- let the caller handle it.

    fp, pathname, description = imp.find_module(name)

    try:
        return imp.load_module(name, fp, pathname, description)
    finally:
        # Since we may exit via an exception, close fp explicitly.
        if fp:
            fp.close()

The best way, I think, is from the official documentation (29.1. imp — Access the import internals):

import imp
import sys

def __import__(name, globals=None, locals=None, fromlist=None):
    # Fast path: see if the module has already been imported.
    try:
        return sys.modules[name]
    except KeyError:
        pass

    # If any of the following calls raises an exception,
    # there's a problem we can't handle -- let the caller handle it.

    fp, pathname, description = imp.find_module(name)

    try:
        return imp.load_module(name, fp, pathname, description)
    finally:
        # Since we may exit via an exception, close fp explicitly.
        if fp:
            fp.close()

__name__ ==“ __main__”是什么?

问题:__name__ ==“ __main__”是什么?

给定以下代码,该if __name__ == "__main__":是什么?

# Threading example
import time, thread

def myfunction(string, sleeptime, lock, *args):
    while True:
        lock.acquire()
        time.sleep(sleeptime)
        lock.release()
        time.sleep(sleeptime)

if __name__ == "__main__":
    lock = thread.allocate_lock()
    thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
    thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

Given the following code, what does the if __name__ == "__main__": do?

# Threading example
import time, thread

def myfunction(string, sleeptime, lock, *args):
    while True:
        lock.acquire()
        time.sleep(sleeptime)
        lock.release()
        time.sleep(sleeptime)

if __name__ == "__main__":
    lock = thread.allocate_lock()
    thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
    thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

回答 0

每当Python解释器读取源文件时,它都会做两件事:

  • 它设置了一些特殊变量,例如__name__,然后

  • 它执行文件中找到的所有代码。

让我们看看它是如何工作的,以及它与您关于__name__我们在Python脚本中经常看到的检查问题的关系。

代码样例

让我们使用稍微不同的代码示例来探索导入和脚本的工作方式。假设以下文件位于foo.py

# Suppose this is foo.py.

print("before import")
import math

print("before functionA")
def functionA():
    print("Function A")

print("before functionB")
def functionB():
    print("Function B {}".format(math.sqrt(100)))

print("before __name__ guard")
if __name__ == '__main__':
    functionA()
    functionB()
print("after __name__ guard")

特殊变量

当Python交互程序读取源文件时,它首先定义一些特殊变量。在这种情况下,我们关心__name__变量。

当您的模块是主程序时

如果您将模块(源文件)作为主程序运行,例如

python foo.py

解释器将硬编码字符串赋值"__main__"__name__变量,即

# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__" 

当您的模块由另一个导入时

另一方面,假设其他模块是主程序,并且它将导入您的模块。这意味着在主程序中或主程序导入的某些其他模块中有这样的语句:

# Suppose this is in some other main program.
import foo

解释器将搜索您的foo.py文件(以及搜索其他一些变体),并在执行该模块之前,它将"foo"导入语句中的名称分配给__name__变量,即

# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"

执行模块的代码

设置特殊变量后,解释器一次执行一次语句,执行模块中的所有代码。您可能想要在代码示例侧面打开另一个窗口,以便您可以按照以下说明进行操作。

总是

  1. 它打印字符串"before import"(不带引号)。

  2. 它将加载math模块并将其分配给名为的变量math。这等效于替换import math为以下内容(请注意,这__import__是Python中的低级函数,它接受字符串并触发实际的导入):

# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
  1. 它输出字符串"before functionA"

  2. 它执行该def块,创建一个功能对象,然后将该功能对象分配给名为的变量functionA

  3. 它输出字符串"before functionB"

  4. 它执行第二个def块,创建另一个函数对象,然后将其分配给名为的变量functionB

  5. 它输出字符串"before __name__ guard"

仅当您的模块是主程序时

  1. 如果您的模块是主程序,那么它将看到__name__确实已将其设置为,"__main__"并且它将调用两个函数,分别输出字符串"Function A""Function B 10.0"

仅当您的模块由另一个导入时

  1. 相反)如果您的模块不是主程序,而是由另一个程序导入的,__name__则将为"foo",不是"__main__",它将跳过if语句的主体。

总是

  1. "after __name__ guard"在两种情况下都将打印字符串。

摘要

总而言之,这是两种情况下的打印内容:

# What gets printed if foo is the main program
before import
before functionA
before functionB
before __name__ guard
Function A
Function B 10.0
after __name__ guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __name__ guard
after __name__ guard

为什么这样工作?

您自然会想知道为什么有人会想要这个。好吧,有时您想编写一个.py文件,该文件既可以被其他程序和/或模块用作模块,也可以作为主程序本身运行。例子:

  • 您的模块是一个库,但是您希望有一个脚本模式,在其中运行一些单元测试或演示。

  • 您的模块仅用作主程序,但是它具有一些单元测试,并且测试框架通过导入.py文件(如脚本)并运行特殊的测试功能来工作。您不希望它只是因为正在导入模块而尝试运行脚本。

  • 您的模块主要用作主程序,但它也为高级用户提供了程序员友好的API。

除了这些示例之外,可以优雅地用Python运行脚本只是设置一些魔术变量并导入脚本。“运行”脚本是导入脚本模块的副作用。

思想的食物

  • 问题:我可以有多个__name__检查块吗?答:这样做很奇怪,但是这种语言不会阻止您。

  • 假设以下内容在中foo2.py。如果python foo2.py在命令行上说会怎样?为什么?

# Suppose this is foo2.py.

def functionA():
    print("a1")
    from foo2 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
if __name__ == "__main__":
    print("m1")
    functionA()
    print("m2")
print("t2")
  • 现在,弄清楚如果删除__name__签入会发生什么foo3.py
# Suppose this is foo3.py.

def functionA():
    print("a1")
    from foo3 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
print("m1")
functionA()
print("m2")
print("t2")
  • 当用作脚本时,它将做什么?当作为模块导入时?
# Suppose this is in foo4.py
__name__ = "__main__"

def bar():
    print("bar")

print("before __name__ guard")
if __name__ == "__main__":
    bar()
print("after __name__ guard")

Whenever the Python interpreter reads a source file, it does two things:

  • it sets a few special variables like __name__, and then

  • it executes all of the code found in the file.

Let’s see how this works and how it relates to your question about the __name__ checks we always see in Python scripts.

Code Sample

Let’s use a slightly different code sample to explore how imports and scripts work. Suppose the following is in a file called foo.py.

# Suppose this is foo.py.

print("before import")
import math

print("before functionA")
def functionA():
    print("Function A")

print("before functionB")
def functionB():
    print("Function B {}".format(math.sqrt(100)))

print("before __name__ guard")
if __name__ == '__main__':
    functionA()
    functionB()
print("after __name__ guard")

Special Variables

When the Python interpeter reads a source file, it first defines a few special variables. In this case, we care about the __name__ variable.

When Your Module Is the Main Program

If you are running your module (the source file) as the main program, e.g.

python foo.py

the interpreter will assign the hard-coded string "__main__" to the __name__ variable, i.e.

# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__" 

When Your Module Is Imported By Another

On the other hand, suppose some other module is the main program and it imports your module. This means there’s a statement like this in the main program, or in some other module the main program imports:

# Suppose this is in some other main program.
import foo

The interpreter will search for your foo.py file (along with searching for a few other variants), and prior to executing that module, it will assign the name "foo" from the import statement to the __name__ variable, i.e.

# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"

Executing the Module’s Code

After the special variables are set up, the interpreter executes all the code in the module, one statement at a time. You may want to open another window on the side with the code sample so you can follow along with this explanation.

Always

  1. It prints the string "before import" (without quotes).

  2. It loads the math module and assigns it to a variable called math. This is equivalent to replacing import math with the following (note that __import__ is a low-level function in Python that takes a string and triggers the actual import):

# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
  1. It prints the string "before functionA".

  2. It executes the def block, creating a function object, then assigning that function object to a variable called functionA.

  3. It prints the string "before functionB".

  4. It executes the second def block, creating another function object, then assigning it to a variable called functionB.

  5. It prints the string "before __name__ guard".

Only When Your Module Is the Main Program

  1. If your module is the main program, then it will see that __name__ was indeed set to "__main__" and it calls the two functions, printing the strings "Function A" and "Function B 10.0".

Only When Your Module Is Imported by Another

  1. (instead) If your module is not the main program but was imported by another one, then __name__ will be "foo", not "__main__", and it’ll skip the body of the if statement.

Always

  1. It will print the string "after __name__ guard" in both situations.

Summary

In summary, here’s what’d be printed in the two cases:

# What gets printed if foo is the main program
before import
before functionA
before functionB
before __name__ guard
Function A
Function B 10.0
after __name__ guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __name__ guard
after __name__ guard

Why Does It Work This Way?

You might naturally wonder why anybody would want this. Well, sometimes you want to write a .py file that can be both used by other programs and/or modules as a module, and can also be run as the main program itself. Examples:

  • Your module is a library, but you want to have a script mode where it runs some unit tests or a demo.

  • Your module is only used as a main program, but it has some unit tests, and the testing framework works by importing .py files like your script and running special test functions. You don’t want it to try running the script just because it’s importing the module.

  • Your module is mostly used as a main program, but it also provides a programmer-friendly API for advanced users.

Beyond those examples, it’s elegant that running a script in Python is just setting up a few magic variables and importing the script. “Running” the script is a side effect of importing the script’s module.

Food for Thought

  • Question: Can I have multiple __name__ checking blocks? Answer: it’s strange to do so, but the language won’t stop you.

  • Suppose the following is in foo2.py. What happens if you say python foo2.py on the command-line? Why?

# Suppose this is foo2.py.

def functionA():
    print("a1")
    from foo2 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
if __name__ == "__main__":
    print("m1")
    functionA()
    print("m2")
print("t2")
  • Now, figure out what will happen if you remove the __name__ check in foo3.py:
# Suppose this is foo3.py.

def functionA():
    print("a1")
    from foo3 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
print("m1")
functionA()
print("m2")
print("t2")
  • What will this do when used as a script? When imported as a module?
# Suppose this is in foo4.py
__name__ = "__main__"

def bar():
    print("bar")

print("before __name__ guard")
if __name__ == "__main__":
    bar()
print("after __name__ guard")

回答 1

通过将脚本作为命令传递给Python解释器来运行脚本时,

python myscript.py

缩进级别为0的所有代码都将执行。可以很好地定义已定义的函数和类,但是不会运行任何代码。与其他语言不同,它没有main()自动运行的功能-main()函数隐式是顶层的所有代码。

在这种情况下,顶级代码是一个if块。 __name__是一个内置变量,其结果为当前模块的名称。但是,如果模块直接运行(如上myscript.py所示),则将__name__其设置为string "__main__"。因此,您可以通过测试来测试您的脚本是直接运行还是通过其他方式导入

if __name__ == "__main__":
    ...

如果将脚本导入另一个模块,则将导入其各种功能和类定义,并执行其顶层代码,但是上述if子句的then-body中的代码将不会运行,因为条件是没见过。作为一个基本示例,请考虑以下两个脚本:

# file one.py
def func():
    print("func() in one.py")

print("top-level in one.py")

if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")
# file two.py
import one

print("top-level in two.py")
one.func()

if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")

现在,如果您将解释器调用为

python one.py

输出将是

top-level in one.py
one.py is being run directly

如果two.py改为运行:

python two.py

你得到

top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly

因此,当模块one加载时,其__name__等于"one"而不是"__main__"

When your script is run by passing it as a command to the Python interpreter,

python myscript.py

all of the code that is at indentation level 0 gets executed. Functions and classes that are defined are, well, defined, but none of their code gets run. Unlike other languages, there’s no main() function that gets run automatically – the main() function is implicitly all the code at the top level.

In this case, the top-level code is an if block. __name__ is a built-in variable which evaluates to the name of the current module. However, if a module is being run directly (as in myscript.py above), then __name__ instead is set to the string "__main__". Thus, you can test whether your script is being run directly or being imported by something else by testing

if __name__ == "__main__":
    ...

If your script is being imported into another module, its various function and class definitions will be imported and its top-level code will be executed, but the code in the then-body of the if clause above won’t get run as the condition is not met. As a basic example, consider the following two scripts:

# file one.py
def func():
    print("func() in one.py")

print("top-level in one.py")

if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")
# file two.py
import one

print("top-level in two.py")
one.func()

if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")

Now, if you invoke the interpreter as

python one.py

The output will be

top-level in one.py
one.py is being run directly

If you run two.py instead:

python two.py

You get

top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly

Thus, when module one gets loaded, its __name__ equals "one" instead of "__main__".


回答 2

__name__变量(imho)的最简单解释如下:

创建以下文件。

# a.py
import b

# b.py
print "Hello World from %s!" % __name__

if __name__ == '__main__':
    print "Hello World again from %s!" % __name__

运行它们将为您提供以下输出:

$ python a.py
Hello World from b!

如您所见,导入模块时,Python globals()['__name__']在此模块中设置模块的名称。同样,在导入时,模块中的所有代码都在运行。由于if语句评估到False这一部分没有执行。

$ python b.py
Hello World from __main__!
Hello World again from __main__!

如您所见,执行文件时,Python globals()['__name__']在该文件中将设置为"__main__"。这次,该if语句求值True并正在运行。

The simplest explanation for the __name__ variable (imho) is the following:

Create the following files.

# a.py
import b

and

# b.py
print "Hello World from %s!" % __name__

if __name__ == '__main__':
    print "Hello World again from %s!" % __name__

Running them will get you this output:

$ python a.py
Hello World from b!

As you can see, when a module is imported, Python sets globals()['__name__'] in this module to the module’s name. Also, upon import all the code in the module is being run. As the if statement evaluates to False this part is not executed.

$ python b.py
Hello World from __main__!
Hello World again from __main__!

As you can see, when a file is executed, Python sets globals()['__name__'] in this file to "__main__". This time, the if statement evaluates to True and is being run.


回答 3

怎么if __name__ == "__main__":办?

概述基础知识:

  • __name__在作为程序入口点的模块中,全局变量为'__main__'。否则,这就是您导入模块的名称。

  • 因此,if仅当模块是程序的入口点时,该块下的代码才会运行。

  • 它允许模块中的代码可由其他模块导入,而无需在导入时执行下面的代码块。


我们为什么需要这个?

开发和测试您的代码

假设您正在编写旨在用作模块的Python脚本:

def do_important():
    """This function does something very important"""

可以通过在底部添加此函数调用测试模块:

do_important()

并使用以下命令运行它(在命令提示符下):

~$ python important.py

问题

但是,如果要将模块导入到另一个脚本:

import important

在导入时,do_important将调用该函数,因此您可能会do_important()在底部注释掉函数调用。

# do_important() # I must remember to uncomment to execute this!

然后,您必须记住是否已注释掉测试函数调用。这种额外的复杂性将意味着您可能会忘记,从而使您的开发过程更加麻烦。

更好的方法

__name__变量指向当前Python解释器所在的命名空间。

在导入的模块中,它是该模块的名称。

但是在主模块(或交互式Python会话,即解释器的Read,Eval,Print Loop或REPL)中,您正在运行其所有内容"__main__"

因此,如果您在执行之前进行检查:

if __name__ == "__main__":
    do_important()

有了以上内容,您的代码将仅在以主模块运行(或从另一个脚本有意调用)时执行。

更好的方法

不过,有一种Python方式可以对此进行改进。

如果我们想从模块外部运行该业务流程怎么办?

如果我们放上我们想在开发和测试这样的函数时使用的代码,然后在执行以下操作时'__main__'立即进行检查:

def main():
    """business logic for when running this module as the primary one!"""
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()

# Here's our payoff idiom!
if __name__ == '__main__':
    main()

现在,我们在模块末尾具有最终功能,如果我们将模块作为主要模块运行,则该功能将运行。

它将允许在不运行该main功能的情况下将该模块及其功能和类导入其他脚本,并且还将允许从其他'__main__'模块运行时调用该模块(及其功能和类),即

import important
important.main()

这个习语也可以在Python文档中的__main__模块说明中找到。该文本指出:

此模块表示解释程序的主程序在其中执行的(否则为匿名)范围-从标准输入,脚本文件或交互式提示中读取的命令。在这种环境中,惯用的“条件脚本”节使脚本运行:

if __name__ == '__main__':
    main()

What does the if __name__ == "__main__": do?

To outline the basics:

  • The global variable, __name__, in the module that is the entry point to your program, is '__main__'. Otherwise, it’s the name you import the module by.

  • So, code under the if block will only run if the module is the entry point to your program.

  • It allows the code in the module to be importable by other modules, without executing the code block beneath on import.


Why do we need this?

Developing and Testing Your Code

Say you’re writing a Python script designed to be used as a module:

def do_important():
    """This function does something very important"""

You could test the module by adding this call of the function to the bottom:

do_important()

and running it (on a command prompt) with something like:

~$ python important.py

The Problem

However, if you want to import the module to another script:

import important

On import, the do_important function would be called, so you’d probably comment out your function call, do_important(), at the bottom.

# do_important() # I must remember to uncomment to execute this!

And then you’ll have to remember whether or not you’ve commented out your test function call. And this extra complexity would mean you’re likely to forget, making your development process more troublesome.

A Better Way

The __name__ variable points to the namespace wherever the Python interpreter happens to be at the moment.

Inside an imported module, it’s the name of that module.

But inside the primary module (or an interactive Python session, i.e. the interpreter’s Read, Eval, Print Loop, or REPL) you are running everything from its "__main__".

So if you check before executing:

if __name__ == "__main__":
    do_important()

With the above, your code will only execute when you’re running it as the primary module (or intentionally call it from another script).

An Even Better Way

There’s a Pythonic way to improve on this, though.

What if we want to run this business process from outside the module?

If we put the code we want to exercise as we develop and test in a function like this and then do our check for '__main__' immediately after:

def main():
    """business logic for when running this module as the primary one!"""
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()

# Here's our payoff idiom!
if __name__ == '__main__':
    main()

We now have a final function for the end of our module that will run if we run the module as the primary module.

It will allow the module and its functions and classes to be imported into other scripts without running the main function, and will also allow the module (and its functions and classes) to be called when running from a different '__main__' module, i.e.

import important
important.main()

This idiom can also be found in the Python documentation in an explanation of the __main__ module. That text states:

This module represents the (otherwise anonymous) scope in which the interpreter’s main program executes — commands read either from standard input, from a script file, or from an interactive prompt. It is this environment in which the idiomatic “conditional script” stanza causes a script to run:

if __name__ == '__main__':
    main()

回答 4

if __name__ == "__main__"是使用(例如)命令从(例如)命令行运行脚本时运行的部分python myscript.py

if __name__ == "__main__" is the part that runs when the script is run from (say) the command line using a command like python myscript.py.


回答 5

怎么if __name__ == "__main__":办?

__name__是存在于所有命名空间中的全局变量(在Python中,global实际上是在模块级别上表示)。它通常是模块的名称(作为str类型)。

但是,作为唯一的特殊情况,无论您运行什么Python进程,如mycode.py:

python mycode.py

否则将匿名全局命名空间的值分配'__main__'__name__

因此,包括最后几行

if __name__ == '__main__':
    main()
  • 在mycode.py脚本的末尾,
  • 当它是由Python进程运行的主要入口点模块时,

将导致脚本的唯一定义main函数运行。

使用此构造的另一个好处:如果程序决定何时,还可以将代码作为模块导入另一个脚本中,然后运行main函数。

import mycode
# ... any amount of other code
mycode.main()

What does if __name__ == "__main__": do?

__name__ is a global variable (in Python, global actually means on the module level) that exists in all namespaces. It is typically the module’s name (as a str type).

As the only special case, however, in whatever Python process you run, as in mycode.py:

python mycode.py

the otherwise anonymous global namespace is assigned the value of '__main__' to its __name__.

Thus, including the final lines

if __name__ == '__main__':
    main()
  • at the end of your mycode.py script,
  • when it is the primary, entry-point module that is run by a Python process,

will cause your script’s uniquely defined main function to run.

Another benefit of using this construct: you can also import your code as a module in another script and then run the main function if and when your program decides:

import mycode
# ... any amount of other code
mycode.main()

回答 6

在这里,有关代码的“如何”的机制有很多不同之处,但是对我而言,直到我理解了“为什么”之后,才有意义。这对新程序员特别有用。

取得文件“ ab.py”:

def a():
    print('A function in ab file');
a()

还有第二个文件“ xy.py”:

import ab
def main():
    print('main function: this is where the action is')
def x():
    print ('peripheral task: might be useful in other projects')
x()
if __name__ == "__main__":
    main()

这段代码实际上在做什么?

当你执行时xy.py,你import ab。import语句在导入时立即运行模块,因此ab的操作要在的其余部分之前执行xy。完成后ab,继续xy

解释器会跟踪运行哪个脚本__name__。当您运行脚本时(无论您使用什么名称),解释器都会调用它"__main__",使其成为运行外部脚本后返回的主脚本或“主”脚本。

从该"__main__"脚本调用的任何其他脚本都被分配了其文件名作为其文件名__name__(例如__name__ == "ab.py")。因此,线if __name__ == "__main__":是解释程序的测试,以确定它是否正在解释/解析最初执行的“ home”脚本,或者它是否正在临时窥视另一个(外部)脚本。这使程序员可以灵活地让脚本在直接执行与在外部执行之间有所不同。

让我们逐步看一下上面的代码,以了解发生了什么,首先关注未缩进的行及其在脚本中出现的顺序。请记住,函数-或def-块在被调用之前不会自行执行任何操作。如果自言自语,口译员可能会说:

  • 打开xy.py作为“主”文件;"__main__"__name__变量中调用它。
  • 使用导入并打开文件__name__ == "ab.py"
  • 哦,有功能。我会记住的。
  • 好的,功能a();我才知道 打印’ ab文件中函数 ‘。
  • 文件结尾;回到"__main__"
  • 哦,有功能。我会记住的。
  • 另一个。
  • 功能x(); 好,打印“ 外围任务:可能在其他项目中有用 ”。
  • 这是什么?一个if声明。好了,条件已经满足(变量__name__已设置为"__main__"),所以我将输入main()函数并打印’ main函数:这是操作所在

最下面的两行表示:“如果这是"__main__"‘或’home’脚本,则执行名为main()“ 的功能。这就是为什么您会def main():在顶部看到一个块的原因,其中包含脚本功能的主要流程。

为什么要实施呢?

还记得我之前说的有关导入语句的内容吗?导入模块时,它不仅会“识别”它并等待进一步的指令-实际上会运行脚本中包含的所有可执行操作。因此,将脚本的内容main()有效地隔离到函数中,将其隔离,以便在被另一个脚本导入时不会立即运行。

同样,会有exceptions,但是通常的做法是main()通常不会在外部调用它。因此,您可能想知道又一件事:如果我们不调用main(),为什么还要调用脚本呢?这是因为许多人使用独立的函数来构造脚本,这些独立的函数旨在独立于文件中的其余代码运行。然后在脚本正文中的其他位置调用它们。这使我想到了这一点:

但是代码没有它就可以工作

恩,那就对了。可以从函数未包含的内联脚本中调用这些单独的main()函数。如果您习惯了(就像我在编程的早期学习阶段那样)构建可以完全满足您需要的内联脚本,并且如果您再次需要该操作,那么您将尝试再次找出它。嗯,您不习惯这种代码的内部结构,因为它的构建更加复杂并且阅读起来也不那么直观。

但这是一个脚本,可能无法从外部调用其功能,因为如果执行该脚本,它将立即开始计算和分配变量。而且,如果您想重用某个功能,则新脚本与旧脚本的关联性可能会很高,以至于变量会冲突。

在拆分独立功能时,您可以通过将其调用到另一个脚本中来重用以前的工作。例如,“ example.py”可能会导入“ xy.py”并调用x(),从而利用“ xy.py” 中的“ x”功能。(也许是将给定文本字符串的第三个单词大写;从数字列表中创建一个NumPy数组并对其进行平方;或者对3D表面进行趋势处理。这种可能性是无限的。)

(顺便说一句,这个问题包含@kindall的答案,它最终帮助我理解了-原因,而不是方法。不幸的是,它被标记为与副本的副本,我认为这是错误的。)

There are lots of different takes here on the mechanics of the code in question, the “How”, but for me none of it made sense until I understood the “Why”. This should be especially helpful for new programmers.

Take file “ab.py”:

def a():
    print('A function in ab file');
a()

And a second file “xy.py”:

import ab
def main():
    print('main function: this is where the action is')
def x():
    print ('peripheral task: might be useful in other projects')
x()
if __name__ == "__main__":
    main()

What is this code actually doing?

When you execute xy.py, you import ab. The import statement runs the module immediately on import, so ab‘s operations get executed before the remainder of xy‘s. Once finished with ab, it continues with xy.

The interpreter keeps track of which scripts are running with __name__. When you run a script – no matter what you’ve named it – the interpreter calls it "__main__", making it the master or ‘home’ script that gets returned to after running an external script.

Any other script that’s called from this "__main__" script is assigned its filename as its __name__ (e.g., __name__ == "ab.py"). Hence, the line if __name__ == "__main__": is the interpreter’s test to determine if it’s interpreting/parsing the ‘home’ script that was initially executed, or if it’s temporarily peeking into another (external) script. This gives the programmer flexibility to have the script behave differently if it’s executed directly vs. called externally.

Let’s step through the above code to understand what’s happening, focusing first on the unindented lines and the order they appear in the scripts. Remember that function – or def – blocks don’t do anything by themselves until they’re called. What the interpreter might say if mumbled to itself:

  • Open xy.py as the ‘home’ file; call it "__main__" in the __name__ variable.
  • Import and open file with the __name__ == "ab.py".
  • Oh, a function. I’ll remember that.
  • Ok, function a(); I just learned that. Printing ‘A function in ab file‘.
  • End of file; back to "__main__"!
  • Oh, a function. I’ll remember that.
  • Another one.
  • Function x(); ok, printing ‘peripheral task: might be useful in other projects‘.
  • What’s this? An if statement. Well, the condition has been met (the variable __name__ has been set to "__main__"), so I’ll enter the main() function and print ‘main function: this is where the action is‘.

The bottom two lines mean: “If this is the "__main__" or ‘home’ script, execute the function called main()“. That’s why you’ll see a def main(): block up top, which contains the main flow of the script’s functionality.

Why implement this?

Remember what I said earlier about import statements? When you import a module it doesn’t just ‘recognize’ it and wait for further instructions – it actually runs all the executable operations contained within the script. So, putting the meat of your script into the main() function effectively quarantines it, putting it in isolation so that it won’t immediately run when imported by another script.

Again, there will be exceptions, but common practice is that main() doesn’t usually get called externally. So you may be wondering one more thing: if we’re not calling main(), why are we calling the script at all? It’s because many people structure their scripts with standalone functions that are built to be run independent of the rest of the code in the file. They’re then later called somewhere else in the body of the script. Which brings me to this:

But the code works without it

Yes, that’s right. These separate functions can be called from an in-line script that’s not contained inside a main() function. If you’re accustomed (as I am, in my early learning stages of programming) to building in-line scripts that do exactly what you need, and you’ll try to figure it out again if you ever need that operation again … well, you’re not used to this kind of internal structure to your code, because it’s more complicated to build and it’s not as intuitive to read.

But that’s a script that probably can’t have its functions called externally, because if it did it would immediately start calculating and assigning variables. And chances are if you’re trying to re-use a function, your new script is related closely enough to the old one that there will be conflicting variables.

In splitting out independent functions, you gain the ability to re-use your previous work by calling them into another script. For example, “example.py” might import “xy.py” and call x(), making use of the ‘x’ function from “xy.py”. (Maybe it’s capitalizing the third word of a given text string; creating a NumPy array from a list of numbers and squaring them; or detrending a 3D surface. The possibilities are limitless.)

(As an aside, this question contains an answer by @kindall that finally helped me to understand – the why, not the how. Unfortunately it’s been marked as a duplicate of this one, which I think is a mistake.)


回答 7

当我们的模块(M.py)中有某些语句时,我们希望在将其作为main(而不是导入)运行时执行该语句,我们可以将这些语句(测试用例,打印语句)放在此if块下。

默认情况下(当模块作为主模块运行而不是导入时),该__name__变量设置为"__main__",导入时,该__name__变量将获得一个不同的值,很可能是模块的名称('M')。这有助于一起运行模块的不同变体,分离其特定的输入和输出语句,以及是否存在测试用例。

简而言之,使用此’ if __name__ == "main"‘块可防止在导入模块时运行(某些)代码。

When there are certain statements in our module (M.py) we want to be executed when it’ll be running as main (not imported), we can place those statements (test-cases, print statements) under this if block.

As by default (when module running as main, not imported) the __name__ variable is set to "__main__", and when it’ll be imported the __name__ variable will get a different value, most probably the name of the module ('M'). This is helpful in running different variants of a modules together, and separating their specific input & output statements and also if there are any test-cases.

In short, use this ‘if __name__ == "main" ‘ block to prevent (certain) code from being run when the module is imported.


回答 8

简而言之,__name__是为每个脚本定义的变量,用于定义脚本是作为主模块运行还是作为导入模块运行。

因此,如果我们有两个脚本;

#script1.py
print "Script 1's name: {}".format(__name__)

#script2.py
import script1
print "Script 2's name: {}".format(__name__)

执行script1的输出是

Script 1's name: __main__

执行script2的输出是:

Script1's name is script1
Script 2's name: __main__

如你看到的, __name__告诉我们哪个代码是“主”模块。这很棒,因为您可以编写代码,而不必担心C / C ++中的结构性问题,在这种情况下,如果文件未实现“ main”功能,则无法将其编译为可执行文件,如果可以,然后它不能用作库。

假设您编写的Python脚本功能出色,并实现了许多对其他用途有用的功能。如果要使用它们,我可以导入您的脚本并使用它们而无需执行您的程序(假设您的代码仅在if __name__ == "__main__":上下文中执行 )。而在C / C ++中,您将必须将这些部分分成一个单独的模块,然后再包含文件。如下图所示;

箭头是导入链接。对于三个试图包含先前模块代码的模块,有六个文件(九个,计算实现文件)和五个链接。除非将其专门编译为库,否则很难将其他代码包含到C项目中。现在将其描述为适用于Python:

您编写了一个模块,如果有人想使用您的代码,他们只需将其导入即可,并且__name__变量可以帮助将程序的可执行部分与库部分分开。

Put simply, __name__ is a variable defined for each script that defines whether the script is being run as the main module or it is being run as an imported module.

So if we have two scripts;

#script1.py
print "Script 1's name: {}".format(__name__)

and

#script2.py
import script1
print "Script 2's name: {}".format(__name__)

The output from executing script1 is

Script 1's name: __main__

And the output from executing script2 is:

Script1's name is script1
Script 2's name: __main__

As you can see, __name__ tells us which code is the ‘main’ module. This is great, because you can just write code and not have to worry about structural issues like in C/C++, where, if a file does not implement a ‘main’ function then it cannot be compiled as an executable and if it does, it cannot then be used as a library.

Say you write a Python script that does something great and you implement a boatload of functions that are useful for other purposes. If I want to use them I can just import your script and use them without executing your program (given that your code only executes within the if __name__ == "__main__": context). Whereas in C/C++ you would have to portion out those pieces into a separate module that then includes the file. Picture the situation below;

The arrows are import links. For three modules each trying to include the previous modules code there are six files (nine, counting the implementation files) and five links. This makes it difficult to include other code into a C project unless it is compiled specifically as a library. Now picture it for Python:

You write a module, and if someone wants to use your code they just import it and the __name__ variable can help to separate the executable portion of the program from the library part.


回答 9

让我们以更抽象的方式看一下答案:

假设我们在以下代码中x.py

...
<Block A>
if __name__ == '__main__':
    <Block B>
...

块A和B,当我们正在运行的运行x.py

但是,y.py例如,当我们运行另一个模块时,仅运行块A(而不运行B),例如,在其中x.py导入了代码并从那里运行代码(例如,当x.py从中调用in函数时y.py)。

Let’s look at the answer in a more abstract way:

Suppose we have this code in x.py:

...
<Block A>
if __name__ == '__main__':
    <Block B>
...

Blocks A and B are run when we are running x.py.

But just block A (and not B) is run when we are running another module, y.py for example, in which x.py is imported and the code is run from there (like when a function in x.py is called from y.py).


回答 10

交互式运行Python时,会为本地__name__变量分配的值__main__。同样,当您从命令行执行Python模块,而不是将其导入另一个模块时,__name__属性被分配为的值__main__,而不是模块的实际名称。通过这种方式,模块可以查看自己的__name__值来自行确定如何使用它们,无论是作为对另一个程序的支持还是作为从命令行执行的主要应用程序。因此,以下习语在Python模块中非常普遍:

if __name__ == '__main__':
    # Do something appropriate here, like calling a
    # main() function defined elsewhere in this module.
    main()
else:
    # Do nothing. This module has been imported by another
    # module that wants to make use of the functions,
    # classes and other useful bits it has defined.

When you run Python interactively the local __name__ variable is assigned a value of __main__. Likewise, when you execute a Python module from the command line, rather than importing it into another module, its __name__ attribute is assigned a value of __main__, rather than the actual name of the module. In this way, modules can look at their own __name__ value to determine for themselves how they are being used, whether as support for another program or as the main application executed from the command line. Thus, the following idiom is quite common in Python modules:

if __name__ == '__main__':
    # Do something appropriate here, like calling a
    # main() function defined elsewhere in this module.
    main()
else:
    # Do nothing. This module has been imported by another
    # module that wants to make use of the functions,
    # classes and other useful bits it has defined.

回答 11

考虑:

if __name__ == "__main__":
    main()

它检查__name__Python脚本的属性是否为"__main__"。换句话说,如果程序本身已执行,则属性将为__main__,因此程序将被执行(在这种情况下,main()函数)。

但是,如果模块使用了您的Python脚本,if则将执行该语句之外的任何代码,因此if \__name__ == "\__main__"仅用于检查该程序是否用作模块,从而决定是否运行该代码。

Consider:

if __name__ == "__main__":
    main()

It checks if the __name__ attribute of the Python script is "__main__". In other words, if the program itself is executed, the attribute will be __main__, so the program will be executed (in this case the main() function).

However, if your Python script is used by a module, any code outside of the if statement will be executed, so if \__name__ == "\__main__" is used just to check if the program is used as a module or not, and therefore decides whether to run the code.


回答 12

在解释任何有关if __name__ == '__main__'它的内容之前,重要的是要了解它是什么__name__以及它做什么。

什么__name__

__name__DunderAlias-可以认为是全局变量(可从模块访问),并且与相似global

它是type(__name__)(yielding <class 'str'>)指示的字符串(如上所述),并且是Python 3Python 2版本的内置标准。

哪里:

它不仅可以在脚本中使用,而且可以在解释器和模块/包中找到。

口译员:

>>> print(__name__)
__main__
>>>

脚本:

test_file.py

print(__name__)

导致 __main__

模块或包装:

somefile.py:

def somefunction():
    print(__name__)

test_file.py:

import somefile
somefile.somefunction()

导致 somefile

请注意,在包或模块中使用时,使用__name__文件名。没有给出实际模块或包路径的路径,但是具有自己的DunderAlias__file__,因此可以这一点。

您应该看到,where __name__,它总是在其中返回主文件(或程序)__main__,并且如果它是一个模块/程序包,或者正在运行其他Python脚本的任何东西,则将在其中返回文件名。起源于。

实践:

作为变量意味着它的值可以被覆盖(“可以”并不意味着“应该”),覆盖的值__name__将导致缺乏可读性。因此,无论出于任何原因都不要这样做。如果您需要一个变量,请定义一个新变量。

始终假定__name__为be 的值__main__或文件名。再次更改此默认值将引起更多混乱,这会带来好处,并进一步导致问题。

例:

>>> __name__ = 'Horrify' # Change default from __main__
>>> if __name__ == 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>

通常,将if __name__ == '__main__'in 包含在脚本中被认为是一种好习惯。

现在回答if __name__ == '__main__'

现在我们知道__name__事物的行为变得更加清晰:

一个if是包含的代码块,如果给定的值是true,将执行流控制语句。我们已经看到这__name__可以采取
__main__导入的文件名导入的文件名。

这意味着,如果__name__等于,__main__则该文件必须是主文件并且必须实际上正在运行(或者它是解释器),而不是导入脚本的模块或包。

如果确实__name__采用了值,__main__那么该代码块中的所有内容都将执行。

这告诉我们,如果正在运行的文件是主文件(或者直接从解释器运行),则必须执行该条件。如果它是一个包,则不应该,并且值不应该是__main__

模块:

__name__ 也可以在模块中使用以定义模块名称

变体:

也可以使用进行其他一些不太常见但有用的事情__name__,我将在这里展示一些:

仅当文件是模块或软件包时才执行:

if __name__ != '__main__':
    # Do some useful things 

如果文件是主文件,则运行一个条件,如果文件不是主文件,则运行另一个条件:

if __name__ == '__main__':
    # Execute something
else:
    # Do some useful things

您也可以使用它在软件包和模块上提供可运行的帮助功能/实用程序,而无需精心使用库。

它还允许模块作为主脚本从命令行运行,这也非常有用。

Before explaining anything about if __name__ == '__main__' it is important to understand what __name__ is and what it does.

What is __name__?

__name__ is a DunderAlias – can be thought of as a global variable (accessible from modules) and works in a similar way to global.

It is a string (global as mentioned above) as indicated by type(__name__) (yielding <class 'str'>), and is an inbuilt standard for both Python 3 and Python 2 versions.

Where:

It can not only be used in scripts but can also be found in both the interpreter and modules/packages.

Interpreter:

>>> print(__name__)
__main__
>>>

Script:

test_file.py:

print(__name__)

Resulting in __main__

Module or package:

somefile.py:

def somefunction():
    print(__name__)

test_file.py:

import somefile
somefile.somefunction()

Resulting in somefile

Notice that when used in a package or module, __name__ takes the name of the file. The path of the actual module or package path is not given, but has its own DunderAlias __file__, that allows for this.

You should see that, where __name__, where it is the main file (or program) will always return __main__, and if it is a module/package, or anything that is running off some other Python script, will return the name of the file where it has originated from.

Practice:

Being a variable means that it’s value can be overwritten (“can” does not mean “should”), overwriting the value of __name__ will result in a lack of readability. So do not do it, for any reason. If you need a variable define a new variable.

It is always assumed that the value of __name__ to be __main__ or the name of the file. Once again changing this default value will cause more confusion that it will do good, causing problems further down the line.

example:

>>> __name__ = 'Horrify' # Change default from __main__
>>> if __name__ == 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>

It is considered good practice in general to include the if __name__ == '__main__' in scripts.

Now to answer if __name__ == '__main__':

Now we know the behaviour of __name__ things become clearer:

An if is a flow control statement that contains the block of code will execute if the value given is true. We have seen that __name__ can take either __main__ or the file name it has been imported from.

This means that if __name__ is equal to __main__ then the file must be the main file and must actually be running (or it is the interpreter), not a module or package imported into the script.

If indeed __name__ does take the value of __main__ then whatever is in that block of code will execute.

This tells us that if the file running is the main file (or you are running from the interpreter directly) then that condition must execute. If it is a package then it should not, and the value will not be __main__.

Modules:

__name__ can also be used in modules to define the name of a module

Variants:

It is also possible to do other, less common but useful things with __name__, some I will show here:

Executing only if the file is a module or package:

if __name__ != '__main__':
    # Do some useful things 

Running one condition if the file is the main one and another if it is not:

if __name__ == '__main__':
    # Execute something
else:
    # Do some useful things

You can also use it to provide runnable help functions/utilities on packages and modules without the elaborate use of libraries.

It also allows modules to be run from the command line as main scripts, which can be also very useful.


回答 13

我认为最好是深入浅出的答案:

__name__:Python中的每个模块都有一个称为的特殊属性__name__。它是一个内置变量,返回模块的名称。

__main__:与其他编程语言一样,Python也具有执行入口点,即main。'__main__' 是执行顶级代码的作用域的名称。基本上,您有两种使用Python模块的方式:直接将其作为脚本运行,或将其导入。当模块作为脚本运行时,其__name__设置为__main__

因此,当模块作为主程序运行时,该__name__属性的值将设置为__main__。否则,的值将__name__ 设置为包含模块的名称。

I think it’s best to break the answer in depth and in simple words:

__name__: Every module in Python has a special attribute called __name__. It is a built-in variable that returns the name of the module.

__main__: Like other programming languages, Python too has an execution entry point, i.e., main. '__main__' is the name of the scope in which top-level code executes. Basically you have two ways of using a Python module: Run it directly as a script, or import it. When a module is run as a script, its __name__ is set to __main__.

Thus, the value of the __name__ attribute is set to __main__ when the module is run as the main program. Otherwise the value of __name__ is set to contain the name of the module.


回答 14

这是从命令行调用Python文件时的特殊功能。通常用于调用“ main()”函数或执行其他适当的启动代码,例如命令行参数处理。

它可以用几种方式编写。另一个是:

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

我并不是说您应该在生产代码中使用它,但是它可以说明没有什么“魔术” if __name__ == '__main__'。在Python文件中调用主函数是一个很好的约定。

It is a special for when a Python file is called from the command line. This is typically used to call a “main()” function or execute other appropriate startup code, like commandline arguments handling for instance.

It could be written in several ways. Another is:

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

I am not saying you should use this in production code, but it serves to illustrate that there is nothing “magical” about if __name__ == '__main__'. It is a good convention for invoking a main function in Python files.


回答 15

系统(Python解释器)为源文件(模块)提供了许多变量。您可以随时获取它们的值,因此,让我们关注__name__变量/属性:

当Python加载源代码文件时,它将执行在其中找到的所有代码。(请注意,它不会调用文件中定义的所有方法和函数,但会定义它们。)

但是,在解释器执行源代码文件之前,它会为该文件定义一些特殊的变量。__名称__是Python为每个源代码文件自动定义的那些特殊变量之一。

如果Python正在将此源代码文件作为主程序加载(即,您运行的文件),那么它将为此文件设置特殊的__name__变量,使其具有值“ __main__”

如果是从另一个模块导入的,则将__name__设置为该模块的名称。

因此,在部分示例中:

if __name__ == "__main__":
   lock = thread.allocate_lock()
   thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
   thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

表示代码块:

lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

仅当您直接运行模块时才会执行;如果另一个模块正在调用/导入该代码块,则该代码块将不会执行,因为__name__的值在该特定实例中将不等于“ main ”。

希望这会有所帮助。

There are a number of variables that the system (Python interpreter) provides for source files (modules). You can get their values anytime you want, so, let us focus on the __name__ variable/attribute:

When Python loads a source code file, it executes all of the code found in it. (Note that it doesn’t call all of the methods and functions defined in the file, but it does define them.)

Before the interpreter executes the source code file though, it defines a few special variables for that file; __name__ is one of those special variables that Python automatically defines for each source code file.

If Python is loading this source code file as the main program (i.e. the file you run), then it sets the special __name__ variable for this file to have a value “__main__”.

If this is being imported from another module, __name__ will be set to that module’s name.

So, in your example in part:

if __name__ == "__main__":
   lock = thread.allocate_lock()
   thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
   thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

means that the code block:

lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

will be executed only when you run the module directly; the code block will not execute if another module is calling/importing it because the value of __name__ will not equal to “main” in that particular instance.

Hope this helps out.


回答 16

if __name__ == "__main__": 基本上是顶级脚本环境,它指定了解释器(“我首先执行的优先级最高”)。

'__main__'是执行顶级代码的作用域的名称。从标准输入,脚本或交互式提示中读取时,模块的__name__设置等于'__main__'

if __name__ == "__main__":
    # Execute only if run as a script
    main()

if __name__ == "__main__": is basically the top-level script environment, and it specifies the interpreter that (‘I have the highest priority to be executed first’).

'__main__' is the name of the scope in which top-level code executes. A module’s __name__ is set equal to '__main__' when read from standard input, a script, or from an interactive prompt.

if __name__ == "__main__":
    # Execute only if run as a script
    main()

回答 17

在本页的所有答案中,我都读了很多东西。我想说的是,如果您知道这件事,那么您肯定会理解这些答案,否则,您仍然会感到困惑。

简而言之,您需要了解以下几点:

  1. import a 操作实际上会运行所有可以在“ a”中运行的内容

  2. 由于第1点,导入时可能不希望所有内容都在“ a”中运行

  3. 为了解决第2点的问题,python允许您进行条件检查

  4. __name__是所有.py模块中的隐式变量;当a.py被导入,的值__name__a.py模块设置为它的文件名“ a“; 当a.py直接使用运行“ python a.py”,该装置a.py在所述入口点,则该值__name__a.py模块被设置为一个字符串__main__

  5. 基于python如何__name__为每个模块设置变量的机制,您知道如何实现第3点吗?答案很简单,对吧?把一个if条件:if __name__ == "__main__": ...; 您甚至可以__name__ == "a"根据您的功能需求放

python特殊之处很重要的一点是第4点!其余只是基本逻辑。

I’ve been reading so much throughout the answers on this page. I would say, if you know the thing, for sure you will understand those answers, otherwise, you are still confused.

To be short, you need to know several points:

  1. import a action actually runs all that can be ran in “a”

  2. Because of point 1, you may not want everything to be run in “a” when importing it

  3. To solve the problem in point 2, python allows you to put a condition check

  4. __name__ is an implicit variable in all .py modules; when a.py is imported, the value of __name__ of a.py module is set to its file name “a“; when a.py is run directly using “python a.py“, which means a.py is the entry point, then the value of __name__ of a.py module is set to a string __main__

  5. Based on the mechanism how python sets the variable __name__ for each module, do you know how to achieve point 3? The answer is fairly easy, right? Put a if condition: if __name__ == "__main__": ...; you can even put if __name__ == "a" depending on your functional need

The important thing that python is special at is point 4! The rest is just basic logic.


回答 18

考虑:

print __name__

上面的输出是__main__

if __name__ == "__main__":
  print "direct method"

上面的陈述是正确的,并显示“ direct method”。假设他们在另一个类中导入了该类,则不会打印“直接方法”,因为在导入时它将设置__name__ equal to "first model name"

Consider:

print __name__

The output for the above is __main__.

if __name__ == "__main__":
  print "direct method"

The above statement is true and prints “direct method”. Suppose if they imported this class in another class it doesn’t print “direct method” because, while importing, it will set __name__ equal to "first model name".


回答 19

您可以使该文件可用作脚本以及可导入模块

fibo.py(名为的模块fibo

# Other modules can IMPORT this MODULE to use the function fib
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

# This allows the file to be used as a SCRIPT
if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

参考:https : //docs.python.org/3.5/tutorial/modules.html

You can make the file usable as a script as well as an importable module.

fibo.py (a module named fibo)

# Other modules can IMPORT this MODULE to use the function fib
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

# This allows the file to be used as a SCRIPT
if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

Reference: https://docs.python.org/3.5/tutorial/modules.html


回答 20

的原因

if __name__ == "__main__":
    main()

主要是为了避免由于直接导入代码而导致的导入锁定问题。你想运行,如果是直接调用的文件(这是main()__name__ == "__main__"情况),,但是如果导入了代码,则导入程序必须从真正的主模块输入代码,以避免导入锁定问题。

副作用是您自动登录支持多个入口点的方法。您可以使用main()作为入口点来运行程序,但不必如此。虽然setup.py期望main(),但其他工具使用备用入口点。例如,要将文件作为gunicorn进程运行,请定义app()函数而不是main()。与一样setup.pygunicorn导入您的代码,因此您不希望它在导入时执行任何操作(由于导入锁定问题)。

The reason for

if __name__ == "__main__":
    main()

is primarily to avoid the import lock problems that would arise from having code directly imported. You want main() to run if your file was directly invoked (that’s the __name__ == "__main__" case), but if your code was imported then the importer has to enter your code from the true main module to avoid import lock problems.

A side-effect is that you automatically sign on to a methodology that supports multiple entry points. You can run your program using main() as the entry point, but you don’t have to. While setup.py expects main(), other tools use alternate entry points. For example, to run your file as a gunicorn process, you define an app() function instead of a main(). Just as with setup.py, gunicorn imports your code so you don’t want it do do anything while it’s being imported (because of the import lock issue).


回答 21

该答案适用于学习Python的Java程序员。每个Java文件通常包含一个公共类。您可以通过两种方式使用该类:

  1. 从其他文件调用类。您只需要将其导入调用程序中即可。

  2. 出于测试目的,单独运行类。

对于后一种情况,该类应包含一个公共的静态void main()方法。在Python中,此目的由全局定义的标签实现'__main__'

This answer is for Java programmers learning Python. Every Java file typically contains one public class. You can use that class in two ways:

  1. Call the class from other files. You just have to import it in the calling program.

  2. Run the class stand alone, for testing purposes.

For the latter case, the class should contain a public static void main() method. In Python this purpose is served by the globally defined label '__main__'.


回答 22

if __name__ == '__main__': 仅当模块作为脚本调用时,才会执行以下代码。

例如,考虑以下模块my_test_module.py

# my_test_module.py

print('This is going to be printed out, no matter what')

if __name__ == '__main__':
    print('This is going to be printed out, only if user invokes the module as a script')

第一种可能性:导入my_test_module.py另一个模块

# main.py

import my_test_module

if __name__ == '__main__':
    print('Hello from main.py')

现在,如果您调用main.py

python main.py 

>> 'This is going to be printed out, no matter what'
>> 'Hello from main.py'

请注意,仅执行print()in中的顶级语句my_test_module


第二种可能性:my_test_module.py作为脚本调用

现在,如果您my_test_module.py以Python脚本运行,则两个print()语句都将执行:

python my_test_module.py

>>> 'This is going to be printed out, no matter what'
>>> 'This is going to be printed out, only if user invokes the module as a script'

The code under if __name__ == '__main__': will only be executed if the module is invoked as a script.

As an example consider the following module my_test_module.py:

# my_test_module.py

print('This is going to be printed out, no matter what')

if __name__ == '__main__':
    print('This is going to be printed out, only if user invokes the module as a script')

1st possibility: Import my_test_module.py in another module

# main.py

import my_test_module

if __name__ == '__main__':
    print('Hello from main.py')

Now if you invoke main.py:

python main.py 

>> 'This is going to be printed out, no matter what'
>> 'Hello from main.py'

Note that only the top-level print() statement in my_test_module is executed.


2nd possibility: Invoke my_test_module.py as a script

Now if you run my_test_module.py as a Python script, both print() statements will be exectued:

python my_test_module.py

>>> 'This is going to be printed out, no matter what'
>>> 'This is going to be printed out, only if user invokes the module as a script'

回答 23

python中的每个模块都有一个名为的属性__name____name__ attribute 的值__main__ 是直接运行模块时(例如)python my_module.py。否则(如您说的那样import my_module)的值__name__ 是模块的名称。

简短说明一下小例子。

#Script test.py

apple = 42

def hello_world():
    print("I am inside hello_world")

if __name__ == "__main__":
    print("Value of __name__ is: ", __name__)
    print("Going to call hello_world")
    hello_world()

我们可以直接执行为

python test.py  

输出量

Value of __name__ is: __main__
Going to call hello_world
I am inside hello_world

现在假设我们从其他脚本中调用上述脚本

#script external_calling.py

import test
print(test.apple)
test.hello_world()

print(test.__name__)

当您执行此

python external_calling.py

输出量

42
I am inside hello_world
test

所以,以上是自我解释,当你调用其他脚本的测试,如果循环__name__test.py不会执行。

Every module in python has a attribute called __name__. The value of __name__ attribute is __main__ when the module is run directly, like python my_module.py. Otherwise (like when you say import my_module) the value of __name__ is the name of the module.

Small example to explain in short.

#Script test.py

apple = 42

def hello_world():
    print("I am inside hello_world")

if __name__ == "__main__":
    print("Value of __name__ is: ", __name__)
    print("Going to call hello_world")
    hello_world()

We can execute this directly as

python test.py  

Output

Value of __name__ is: __main__
Going to call hello_world
I am inside hello_world

Now suppose we call above script from other script

#script external_calling.py

import test
print(test.apple)
test.hello_world()

print(test.__name__)

When you execute this

python external_calling.py

Output

42
I am inside hello_world
test

So, above is self explanatory that when you call test from other script, if loop __name__ in test.py will not execute.


回答 24

如果此.py文件是由其他.py文件导入的,则“ if语句”下的代码将不会执行。

如果此.py是python this_py.py在shell下运行,或在Windows中双击。“ if语句”下的代码将被执行。

通常是为了测试而编写的。

If this .py file are imported by other .py files, the code under “the if statement” will not be executed.

If this .py are run by python this_py.py under shell, or double clicked in Windows. the code under “the if statement” will be executed.

It is usually written for testing.


回答 25

如果python解释器正在运行特定模块,则__name__全局变量将具有值"__main__"

  def a():
      print("a")
  def b():
      print("b")

  if __name__ == "__main__": 

          print ("you can see me" )
          a()
  else: 

          print ("You can't see me")
          b()

运行此脚本打印件时,您可以看到我

一个

如果您导入此文件,请说A到文件B并执行文件B,则if __name__ == "__main__"文件A中的文件将变为false,因此将其打印出来 您看不到我

b

If the python interpreter is running a particular module then __name__ global variable will have value "__main__"

  def a():
      print("a")
  def b():
      print("b")

  if __name__ == "__main__": 

          print ("you can see me" )
          a()
  else: 

          print ("You can't see me")
          b()

When you run this script prints you can see me

a

If you import this file say A to file B and execute the file B then if __name__ == "__main__" in file A becomes false, so it prints You can’t see me

b


回答 26

所有答案都对功能进行了解释。但是,我将提供其用法的一个示例,这可能有助于进一步澄清该概念。

假设您有两个Python文件a.py和b.py。现在,a.py导入b.py。我们运行a.py文件,首先执行“ import b.py”代码。在其余的a.py代码运行之前,文件b.py中的代码必须完全运行。

在b.py代码中,有一些代码是该文件b.py独有的,我们不希望导入b.py文件的任何其他文件(b.py文件除外)来运行它。

这就是这行代码检查的内容。如果它是运行代码的主文件(即b.py)(在这种情况下不是)(运行a.py是主文件),则仅执行代码。

All the answers have pretty much explained the functionality. But I will provide one example of its usage which might help clearing out the concept further.

Assume that you have two Python files, a.py and b.py. Now, a.py imports b.py. We run the a.py file, where the “import b.py” code is executed first. Before the rest of the a.py code runs, the code in the file b.py must run completely.

In the b.py code there is some code that is exclusive to that file b.py and we don’t want any other file (other than b.py file), that has imported the b.py file, to run it.

So that is what this line of code checks. If it is the main file (i.e., b.py) running the code, which in this case it is not (a.py is the main file running), then only the code gets executed.


回答 27

创建一个文件a.py

print(__name__) # It will print out __main__

__name__始终等于__main__该文件直接运行时表明它是主文件。

在同一目录中创建另一个文件b.py

import a  # Prints a

运行。它将打印一个,即被导入文件的名称。

因此,为了显示同一文件的两种不同行为,这是一个常用的技巧:

# Code to be run when imported into another python file

if __name__ == '__main__':
    # Code to be run only when run directly

Create a file, a.py:

print(__name__) # It will print out __main__

__name__ is always equal to __main__ whenever that file is run directly showing that this is the main file.

Create another file, b.py, in the same directory:

import a  # Prints a

Run it. It will print a, i.e., the name of the file which is imported.

So, to show two different behavior of the same file, this is a commonly used trick:

# Code to be run when imported into another python file

if __name__ == '__main__':
    # Code to be run only when run directly

回答 28

如果name ==’ main ‘:

我们__name__ == '__main__':经常查看。

它检查是否正在导入模块。

换句话说,if仅当代码直接运行时,才会执行该块中的代码。这里的directly意思是not imported

让我们看一下使用打印模块名称的简单代码的作用:

# test.py
def test():
   print('test module name=%s' %(__name__))

if __name__ == '__main__':
   print('call test()')
   test()

如果我们直接通过运行代码python test.py,则模块名称为__main__

call test()
test module name=__main__

if name == ‘main‘:

We see if __name__ == '__main__': quite often.

It checks if a module is being imported or not.

In other words, the code within the if block will be executed only when the code runs directly. Here directly means not imported.

Let’s see what it does using a simple code that prints the name of the module:

# test.py
def test():
   print('test module name=%s' %(__name__))

if __name__ == '__main__':
   print('call test()')
   test()

If we run the code directly via python test.py, the module name is __main__:

call test()
test module name=__main__

回答 29

简而言之,就像C编程语言中的main函数一样,它是运行文件的入口。

Simply, it is the entry point to run the file, like the main function in the C programming language.