The rules are quite simple: the same module is evaluated only once, in other words, the module-level scope is executed just once. If the module, once evaluated, is imported again, it's second evaluation is skipped and the resolved already exports are used.
Using from to import module You can import only a small part of the module i.e., only the required functions and variable names from the module instead of importing full code. When you want only specific things to be imported, you can make use of “from” keyword to import what you want.
Import multiple modulesYou can write multiple modules separated by commas after the import statement, but this is not recommended in PEP8. Imports should usually be on separate lines. If you use from to import functions, variables, classes, etc., as explained next, you can separate them with a comma.
All you have to do is place a . py or . ipy file in the ~/. ipython/profile_default/startup directory and it will automatically be executed.
Changing the name of your module is not necessary. Rather, you can use absolute_import to change the importing behavior. For example with stem/socket.py I import the socket module as follows:
from __future__ import absolute_import
import socket
This only works with Python 2.5 and above; it's enabling behavior that is the default in Python 3.0 and higher. Pylint will complain about the code but it's perfectly valid.
Actually, solving this is rather easy, but the implementation will always be a bit fragile, because it depends python import mechanism's internals and they are subject to change in future versions.
(the following code shows how to load both local and non-local modules and how they may coexist)
def import_non_local(name, custom_name=None):
import imp, sys
custom_name = custom_name or name
f, pathname, desc = imp.find_module(name, sys.path[1:])
module = imp.load_module(custom_name, f, pathname, desc)
f.close()
return module
# Import non-local module, use a custom name to differentiate it from local
# This name is only used internally for identifying the module. We decide
# the name in the local scope by assigning it to the variable calendar.
calendar = import_non_local('calendar','std_calendar')
# import local module normally, as calendar_local
import calendar as calendar_local
print calendar.Calendar
print calendar_local
The best solution, if possible, is to avoid naming your modules with the same name as standard-library or built-in module names.
The only way to solve this problem is to hijack the internal import machinery yourself. This is not easy, and fraught with peril. You should avoid the grail shaped beacon at all costs because the peril is too perilous.
Rename your module instead.
If you want to learn how to hijack the internal import machinery, here is where you would go about finding out how to do this:
There are sometimes good reasons to get into this peril. The reason you give is not among them. Rename your module.
If you take the perilous path, one problem you will encounter is that when you load a module it ends up with an 'official name' so that Python can avoid ever having to parse the contents of that module ever again. A mapping of the 'official name' of a module to the module object itself can be found in sys.modules
.
This means that if you import calendar
in one place, whatever module is imported will be thought of as the module with the official name calendar
and all other attempts to import calendar
anywhere else, including in other code that's part of the main Python library, will get that calendar.
It might be possible to design a customer importer using the imputil module in Python 2.x that caused modules loaded from certain paths to look up the modules they were importing in something other than sys.modules
first or something like that. But that's an extremely hairy thing to be doing, and it won't work in Python 3.x anyway.
There is an extremely ugly and horrible thing you can do that does not involve hooking the import mechanism. This is something you should probably not do, but it will likely work. It turns your calendar
module into a hybrid of the system calendar module and your calendar module. Thanks to Boaz Yaniv for the skeleton of the function I use. Put this at the beginning of your calendar.py
file:
import sys
def copy_in_standard_module_symbols(name, local_module):
import imp
for i in range(0, 100):
random_name = 'random_name_%d' % (i,)
if random_name not in sys.modules:
break
else:
random_name = None
if random_name is None:
raise RuntimeError("Couldn't manufacture an unused module name.")
f, pathname, desc = imp.find_module(name, sys.path[1:])
module = imp.load_module(random_name, f, pathname, desc)
f.close()
del sys.modules[random_name]
for key in module.__dict__:
if not hasattr(local_module, key):
setattr(local_module, key, getattr(module, key))
copy_in_standard_module_symbols('calendar', sys.modules[copy_in_standard_module_symbols.__module__])
The accepted solution contains a now-deprecated approach.
The importlib documentation here gives a good example of the more appropriate way to load a module directly from a file path for python >= 3.5:
import importlib.util
import sys
# For illustrative purposes.
import tokenize
file_path = tokenize.__file__ # returns "/path/to/tokenize.py"
module_name = tokenize.__name__ # returns "tokenize"
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)
So, you can load any .py file from a path and set the module name to be whatever you want. So just adjust the module_name
to be whatever custom name you'd like the module to have upon importing.
To load a package instead of a single file, file_path
should be the path to the package's root __init__.py
I'd like to offer my version, which is a combination of Boaz Yaniv's and Omnifarious's solution. It will import the system version of a module, with two main differences from the previous answers:
Put this somewhere accessible so you can call it (I have mine in my __init__.py file):
class SysModule(object):
pass
def import_non_local(name, local_module=None, path=None, full_name=None, accessor=SysModule()):
import imp, sys, os
path = path or sys.path[1:]
if isinstance(path, basestring):
path = [path]
if '.' in name:
package_name = name.split('.')[0]
f, pathname, desc = imp.find_module(package_name, path)
if pathname not in __path__:
__path__.insert(0, pathname)
imp.load_module(package_name, f, pathname, desc)
v = import_non_local('.'.join(name.split('.')[1:]), None, pathname, name, SysModule())
setattr(accessor, package_name, v)
if local_module:
for key in accessor.__dict__.keys():
setattr(local_module, key, getattr(accessor, key))
return accessor
try:
f, pathname, desc = imp.find_module(name, path)
if pathname not in __path__:
__path__.insert(0, pathname)
module = imp.load_module(name, f, pathname, desc)
setattr(accessor, name, module)
if local_module:
for key in accessor.__dict__.keys():
setattr(local_module, key, getattr(accessor, key))
return module
return accessor
finally:
try:
if f:
f.close()
except:
pass
I wanted to import mysql.connection, but I had a local package already called mysql (the official mysql utilities). So to get the connector from the system mysql package, I replaced this:
import mysql.connector
With this:
import sys
from mysql.utilities import import_non_local # where I put the above function (mysql/utilities/__init__.py)
import_non_local('mysql.connector', sys.modules[__name__])
# This unmodified line further down in the file now works just fine because mysql.connector has actually become part of the namespace
self.db_conn = mysql.connector.connect(**parameters)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With