问题
According to the documentation, six supports adding custom renames to six.moves:
six.add_move(item)
Add item to the
six.moves
mapping. item should be aMovedAttribute
orMovedModule
instance.
And:
class six.MovedModule(name, old_mod, new_mod)
Create a mapping for
six.moves
called name that references different modules in Python 2 and 3.old_mod
is the name of the Python 2 module.new_mod
is the name of the Python 3 module.
However, this code yields an ImportError
for me:
from six import add_move, MovedModule
add_move(MovedModule('mock', 'mock', 'unittest.mock'))
from six.moves.mock import MagicMock
When I run it on Python 3.4.2 using six 1.9.0 I get this error:
Traceback (most recent call last):
File "test_six_moves.py", line 2, in <module>
from six.moves.mock import MagicMock
ImportError: No module named 'six.moves.mock'
The builtin moves are working just fine. How do I get this to work?
回答1:
You can't import the name from within the move. Use:
from __future__ import print_function
from six import add_move, MovedModule
add_move(MovedModule('mock', 'mock', 'unittest.mock'))
from six.moves import mock
print(mock.MagicMock)
This will give you:
# Python 2
<class 'mock.MagicMock'>
# Python 3
<class 'unittest.mock.MagicMock'>
Note that importing from within a move works for the ones that ship with six
. For example: from six.moves.configparser import ConfigParser
works.
This piece of code (from six.py) is why:
for attr in _moved_attributes:
setattr(_MovedItems, attr.name, attr)
if isinstance(attr, MovedModule):
_importer._add_module(attr, "moves." + attr.name)
In fact, if you ran the following (meddling with private attributes is of course not recommended), your import would work:
import six
mod = six.MovedModule('mock', 'mock', 'unittest.mock')
six.add_move(mod)
six._importer._add_module(mod, "moves." + mod.name)
来源:https://stackoverflow.com/questions/28215214/how-to-add-custom-renames-in-six