Force Python import to be absolute (ignore local package directory)
Question:
Is there a way to force an import to be absolute instead of relative?
I am “overriding” the Python standard library json
module, so in my projects I always use the correct encoder and parameters:
project/foo/json.py
: (mark this filename)
import json as pyjson
class ComplexEncoder(pyjson.JSONEncoder):
def default(self, obj):
if hasattr(obj, 'isoformat'):
return obj.isoformat()
else:
if type(obj) == file:
return "filestream"
raise TypeError, 'Object of type %s with value of %s is not JSON serializable' % (type(obj), repr(obj))
def dumps(data):
return pyjson.dumps(data, cls=ComplexEncoder, check_circular=False, separators=(',', ':'), ensure_ascii=False)
def loads(data):
return pyjson.loads(data)
When I import this file I get the dreaded AttributeError: 'module' object has no attribute 'JSONEncoder'
.
A print(pyjson.__file__)
confirms my suspicion that import json as pyjson
imports json
from the local package instead of from the Python standard library.
Is there a way to force the import to be absolute, so the local directory is ignored?
Answers:
If your “json” module is inside a package, then this will fix it:
from __future__ import absolute_import
With that __future__
statement, imports will be absolute be default – i.e. it will only look for a top-level module or file called json
.
If you need to import your local one, you can either do import foo.json
, or you can explictly ask for a relative import using from . import json
or from .json import dumps
.
(I am assuming you’re using Python 2).
You can delete the self path from the sys.path:
self_dir = os.path.dirname(os.path.realpath(__file__))
if self_dir in sys.path:
sys.path.remove(self_dir)
Then import the json as regular.
If you need to import anything from the local directory, just append the path to the sys.path and import what you need:
sys.path.append(self_dir)
from local_module import *
Is there a way to force an import to be absolute instead of relative?
I am “overriding” the Python standard library json
module, so in my projects I always use the correct encoder and parameters:
project/foo/json.py
: (mark this filename)
import json as pyjson
class ComplexEncoder(pyjson.JSONEncoder):
def default(self, obj):
if hasattr(obj, 'isoformat'):
return obj.isoformat()
else:
if type(obj) == file:
return "filestream"
raise TypeError, 'Object of type %s with value of %s is not JSON serializable' % (type(obj), repr(obj))
def dumps(data):
return pyjson.dumps(data, cls=ComplexEncoder, check_circular=False, separators=(',', ':'), ensure_ascii=False)
def loads(data):
return pyjson.loads(data)
When I import this file I get the dreaded AttributeError: 'module' object has no attribute 'JSONEncoder'
.
A print(pyjson.__file__)
confirms my suspicion that import json as pyjson
imports json
from the local package instead of from the Python standard library.
Is there a way to force the import to be absolute, so the local directory is ignored?
If your “json” module is inside a package, then this will fix it:
from __future__ import absolute_import
With that __future__
statement, imports will be absolute be default – i.e. it will only look for a top-level module or file called json
.
If you need to import your local one, you can either do import foo.json
, or you can explictly ask for a relative import using from . import json
or from .json import dumps
.
(I am assuming you’re using Python 2).
You can delete the self path from the sys.path:
self_dir = os.path.dirname(os.path.realpath(__file__))
if self_dir in sys.path:
sys.path.remove(self_dir)
Then import the json as regular.
If you need to import anything from the local directory, just append the path to the sys.path and import what you need:
sys.path.append(self_dir)
from local_module import *