从包中导入阴影模块
Import a shadowed module from a package
这是我的包结构:
.
├── src
│ ├── damastes
│ │ ├── __init__.py
│ │ ├── main.py
│ │ └── run.py
__init__.py
:
from .run import *
run.py
:
...
_ARGS
...
def _path_compare(path_x: Path, path_y: Path) -> Ord:
return (
...
if _ARGS.sort_lex
else ...
)
...
def run()
...
我可以从 run
模块导入任何我想要的 ,但不能导入模块 run
本身。直到我不得不提供猴子补丁的模块才给我带来不便:
test.py
:
from src.damastes.run import _path_compare
...
def test_path_compare(monkeypatch):
args = RestrictedDotDict(copy.deepcopy(CLEAN_CONTEXT_PARAMS))
args.sort_lex = True
monkeypatch.setattr(src.damastes.run, "_ARGS", args)
assert _path_compare("alfa", "alfa") == 0
我的问题是 monkeypatch.setattr()
需要 module 作为第一个参数,但我不能提供它。 src.damastes.run
实际上是一个函数。应该如此。 “短路”是故意的。
错误:
AttributeError: <function run at 0x7f3392b9f790> has no attribute '_ARGS'
实验上,我提供 src.damastes
:
AttributeError: <module 'src.damastes' from '/src/damastes/__init__.py'> has no attribute '_ARGS'
当然没有。有没有办法在不重构现有 package/import 解决方案的情况下向 monkeypatch.setattr()
提供 run
模块?
顺便说一句,from src.damastes.run import _path_compare
部分以某种方式起作用。
我不得不重命名模块:run.py
-> shoot.py
:
init.py
:
from .shoot import *
test.py
:
import src.damastes.shoot as shoot
...
class TestNonPureHelpers:
def new_args(self):
return RestrictedDotDict(copy.deepcopy(CLEAN_CONTEXT_PARAMS))
def test_path_compare(self, monkeypatch):
args = self.new_args()
monkeypatch.setattr(shoot, "_ARGS", args)
args.sort_lex = True
assert shoot._path_compare("10alfa", "2bravo") == -1
args.sort_lex = False # Sort naturally.
assert shoot._path_compare("10alfa", "2bravo") == 1
解决方案有点明显,但有点不舒服。对于像 Python 这样的 ad hoc 语言来说并非不可想象,但它违背了作用域的想法。模块内的名称不应与模块名称冲突。
是否只有重命名解决方案?
这是我的包结构:
.
├── src
│ ├── damastes
│ │ ├── __init__.py
│ │ ├── main.py
│ │ └── run.py
__init__.py
:
from .run import *
run.py
:
...
_ARGS
...
def _path_compare(path_x: Path, path_y: Path) -> Ord:
return (
...
if _ARGS.sort_lex
else ...
)
...
def run()
...
我可以从 run
模块导入任何我想要的 ,但不能导入模块 run
本身。直到我不得不提供猴子补丁的模块才给我带来不便:
test.py
:
from src.damastes.run import _path_compare
...
def test_path_compare(monkeypatch):
args = RestrictedDotDict(copy.deepcopy(CLEAN_CONTEXT_PARAMS))
args.sort_lex = True
monkeypatch.setattr(src.damastes.run, "_ARGS", args)
assert _path_compare("alfa", "alfa") == 0
我的问题是 monkeypatch.setattr()
需要 module 作为第一个参数,但我不能提供它。 src.damastes.run
实际上是一个函数。应该如此。 “短路”是故意的。
错误:
AttributeError: <function run at 0x7f3392b9f790> has no attribute '_ARGS'
实验上,我提供 src.damastes
:
AttributeError: <module 'src.damastes' from '/src/damastes/__init__.py'> has no attribute '_ARGS'
当然没有。有没有办法在不重构现有 package/import 解决方案的情况下向 monkeypatch.setattr()
提供 run
模块?
from src.damastes.run import _path_compare
部分以某种方式起作用。
我不得不重命名模块:run.py
-> shoot.py
:
init.py
:
from .shoot import *
test.py
:
import src.damastes.shoot as shoot
...
class TestNonPureHelpers:
def new_args(self):
return RestrictedDotDict(copy.deepcopy(CLEAN_CONTEXT_PARAMS))
def test_path_compare(self, monkeypatch):
args = self.new_args()
monkeypatch.setattr(shoot, "_ARGS", args)
args.sort_lex = True
assert shoot._path_compare("10alfa", "2bravo") == -1
args.sort_lex = False # Sort naturally.
assert shoot._path_compare("10alfa", "2bravo") == 1
解决方案有点明显,但有点不舒服。对于像 Python 这样的 ad hoc 语言来说并非不可想象,但它违背了作用域的想法。模块内的名称不应与模块名称冲突。
是否只有重命名解决方案?