/usr/local/lib/python2.7/dist-packages/cv2/__init__.py in<module>()78# make IDE's (PyCharm) autocompletion happy---->9from.cv2 import*1011# wildcard import above does not import "private" variables like __version__ImportError: libSM.so.6: cannot open shared object file:No such file or directory
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
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
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.
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:
def __getattr__(name):if name =='y':return3raiseAttributeError(f"module '{__name__}' has no attribute '{name}'")
other =4
用法:
>>>import module>>> module.y3>>> module.other4>>> module.nosuchTraceback(most recent call last):File"<stdin>", line 1,in<module>File"module.py", line 4,in __getattr__raiseAttributeError(f"module '{__name__}' has no attribute '{name}'")AttributeError: module 'module' has no attribute 'nosuch'
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.
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):raiseAttributeError(
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_getattrreturn func
用法(请注意下划线),位于the_module.py:
@module_propertydef _thing():return'hello'
然后:
import the_moduleprint(the_module.thing)# prints 'hello'
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__'notin globals():# constant prolog for having module properties / supports reload()print"PropertyModule stub execution", __name__
import sys, types
classPropertyModule(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 =7def 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'"
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
# python -m pip install forbiddenfruitfrom forbiddenfruit import curse
from types importModuleType# 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
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:
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
Python2.7.3(default,Aug12012,05:14:39)[GCC 4.6.3] on linux2Type"help","copyright","credits"or"license"for more information.>>>import mechanizeTraceback(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?
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.
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”。这提供了已安装软件包的位置。
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.
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.
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.
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.
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.
Traceback(most recent call last):File"telegram.py", line 2,in<module>from telegram.ext importUpdaterFile"$USER/telegram.py", line 2,in<module>from telegram.ext importUpdaterImportError:No module named 'telegram.ext';'telegram'isnot a package
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).
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
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.
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>
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.
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
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.
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.
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.
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.
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.
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.
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).
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.
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):
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):
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.
Python3.5.2(default,Sep142017,22:51:06)[GCC 5.4.020160609] on linux
Type"help","copyright","credits"or"license"for more information.>>>from hellostackoverflow import hellostackoverflow
>>> hellostackoverflow.greeting()'Hello Stack Overflow!'
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:
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.
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)
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.
$ python3 -c "import os, sys; print(os.environ['PYTHONPATH']); print(sys.path) if 'PYTHONPATH' in sorted(os.environ) else print('PYTHONPATH is not defined')"
>>> 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 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')"
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__
raiseKeyError(key)fromNoneKeyError:'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'
>>>
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错误的原因。
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.
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.
“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.
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 datedel 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
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它将返回:
Thisis a function in dir package_b
going to call a function in dir package_a
------------------------------Thisis 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
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??
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)
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.
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
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?
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
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’):
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.
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+
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
from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery importSourceFileLoader
spec = spec_from_loader("module.name",SourceFileLoader("module.name","/path/to/file.py"))
mod = module_from_spec(spec)
spec.loader.exec_module(mod)
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 pathimport bar
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:
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!
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 =Nonetry:# 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()exceptExceptionas ec:# Simple error printing# Insert "sophisticated" stuff hereprint(ec)finally:return module
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.
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)
##################### ### classloader.py ### ####################import sys, types
def _get_mod(modulePath):try:
aMod = sys.modules[modulePath]ifnot isinstance(aMod, types.ModuleType):raiseKeyErrorexceptKeyError:# 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 isnotNone:ifnot issubclass(aClass, parentClass):raiseTypeError(u"%s is not a subclass of %s"%(fullClassName, parentClass))# Return a reference to the class itself, not an instantiated object.return aClass
######################## Usage ########################classStorageManager:passclassStorageManagerMySQL(StorageManager):passdef storage_object(aFullClassName, allOptions={}):
aStoreClass = _get_class(aFullClassName,StorageManager)return aStoreClass(allOptions)
###################
## #
## 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 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 directoryimport tacklelib as tkl
tkl.tkl_init(tkl)# cleanupdel 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 hereprint("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
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`
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.
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')
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.
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 hereif 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
ifnot libPath in sys.path: sys.path.append(libPath)import pyfunc as pf
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 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.
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)whileTrue:
p = p.parent
ifnot p:breakifnot p.is_dir():break
inits =[f for f in p.iterdir()if f.name =='__init__.py']ifnot inits:break
paths.append(p.stem)return'.'.join(reversed(paths))
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.
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]exceptKeyError: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()
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()
# 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
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
It prints the string "before import" (without quotes).
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")
It prints the string "before functionA".
It executes the def block, creating a function object, then assigning that function object to a variable called functionA.
It prints the string "before functionB".
It executes the second def block, creating another function object, then assigning it to a variable called functionB.
It prints the string "before __name__ guard".
Only When Your Module Is the Main Program
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
(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
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")
# file one.pydef 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.pyimport 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
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.pyimport b
和
# b.pyprint"Hello World from %s!"% __name__
if __name__ =='__main__':print"Hello World again from %s!"% __name__
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.
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()
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.
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。
__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__.
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()
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()
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.)
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.
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.
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.
...
<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).
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.
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.
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.
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.
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.
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.
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.
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__": 基本上是顶级脚本环境,它指定了解释器(“我首先执行的优先级最高”)。
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()
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:
import a action actually runs all that can be ran in “a”
Because of point 1, you may not want everything to be run in “a” when importing it
To solve the problem in point 2, python allows you to put a condition check
__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__
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"。
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 fibdef fib(n):# write Fibonacci series up to n
a, b =0,1while b < n:print(b, end=' ')
a, b = b, a+b
print()# This allows the file to be used as a SCRIPTif __name__ =="__main__":import sys
fib(int(sys.argv[1]))
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]))
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).
This answer is for Java programmers learning Python.
Every Java file typically contains one public class. You can use that class in two ways:
Call the class from other files. You just have to import it in the calling program.
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.pyprint('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.pyimport 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'
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'
#Script test.py
apple =42def 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.pyimport test
print(test.apple)
test.hello_world()print(test.__name__)
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.
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 fileif __name__ =='__main__':# Code to be run only when run directly