导入时是否有退出模块的命令,例如函数的 return
Is there a command to exit a module when imported, like return for a function
当您在 python 中导入模块时,模块代码为“运行”。有时在模块中有分支逻辑很有用,例如检查包版本或平台或其他。有没有办法在到达文件末尾之前退出整个模块执行,相当于函数中的早期 return?
如果模块 运行 作为脚本,您可以 exit() 但这会主动引发异常并终止整个过程。我只想说,你已经完成了,不要 运行 下面的任何代码。
基本上我可以改造这个
if not <condition>:
MY_CONSTANT = 3.14
class blah():
...
def foo(x):
...
# rest of module....
进入
if <condition>:
return from module
MY_CONSTANT = 3.14
class blah():
...
def foo(x):
...
# rest of module....
主要是为了让我不必编写很多看起来很奇怪的额外缩进级别的代码。
有点蹩脚,但如果你有一个模块 mylib.py
看起来像这样:
import sys
print("mylib - before sys.exit")
sys.exit(0)
print("mylib - after sys.exit")
然后是导入它的另一个文件:
try:
import mylib
except SystemExit:
pass
print("Done")
输出:
mylib - before sys.exit
Done
>>>
您可以创建自定义 Loader
that special-cases e.g. ImportError
(1) as a shortcut to stop module execution. This can be registered via a custom Finder
at sys.meta_path
。
所以如果你有以下模块要导入:
# foo.py
x = 1
raise ImportError # stop module execution here
y = 2
您可以使用以下 finder/loader 导入该模块。它将一直执行到到达 raise ImportError
.
为止
import importlib
class Loader(importlib.machinery.SourceFileLoader):
def exec_module(self, module):
try:
super().exec_module(module)
except ImportError: # the module chose to stop executing
pass
class Finder(importlib.machinery.PathFinder):
@classmethod
def find_spec(cls, fullname, path=None, target=None):
spec = super().find_spec(fullname, path, target)
if spec is not None:
spec.loader = Loader(spec.name, spec.origin) # register the custom loader
return spec
import sys
sys.meta_path.insert(2, Finder()) # from now on the custom finder will be queried for imports
import foo
print(foo.x) # prints 1
print(foo.y) # raises AttributeError
(1) 使用 ImportError
来指示快捷方式显然有其缺点,例如,如果您的模块试图导入其他不存在的东西,这不会被报告为错误,但是模块只是停止执行。所以最好改用一些自定义异常。我只是为了示例而使用 ImportError
。
当您在 python 中导入模块时,模块代码为“运行”。有时在模块中有分支逻辑很有用,例如检查包版本或平台或其他。有没有办法在到达文件末尾之前退出整个模块执行,相当于函数中的早期 return?
如果模块 运行 作为脚本,您可以 exit() 但这会主动引发异常并终止整个过程。我只想说,你已经完成了,不要 运行 下面的任何代码。
基本上我可以改造这个
if not <condition>:
MY_CONSTANT = 3.14
class blah():
...
def foo(x):
...
# rest of module....
进入
if <condition>:
return from module
MY_CONSTANT = 3.14
class blah():
...
def foo(x):
...
# rest of module....
主要是为了让我不必编写很多看起来很奇怪的额外缩进级别的代码。
有点蹩脚,但如果你有一个模块 mylib.py
看起来像这样:
import sys
print("mylib - before sys.exit")
sys.exit(0)
print("mylib - after sys.exit")
然后是导入它的另一个文件:
try:
import mylib
except SystemExit:
pass
print("Done")
输出:
mylib - before sys.exit
Done
>>>
您可以创建自定义 Loader
that special-cases e.g. ImportError
(1) as a shortcut to stop module execution. This can be registered via a custom Finder
at sys.meta_path
。
所以如果你有以下模块要导入:
# foo.py
x = 1
raise ImportError # stop module execution here
y = 2
您可以使用以下 finder/loader 导入该模块。它将一直执行到到达 raise ImportError
.
import importlib
class Loader(importlib.machinery.SourceFileLoader):
def exec_module(self, module):
try:
super().exec_module(module)
except ImportError: # the module chose to stop executing
pass
class Finder(importlib.machinery.PathFinder):
@classmethod
def find_spec(cls, fullname, path=None, target=None):
spec = super().find_spec(fullname, path, target)
if spec is not None:
spec.loader = Loader(spec.name, spec.origin) # register the custom loader
return spec
import sys
sys.meta_path.insert(2, Finder()) # from now on the custom finder will be queried for imports
import foo
print(foo.x) # prints 1
print(foo.y) # raises AttributeError
(1) 使用 ImportError
来指示快捷方式显然有其缺点,例如,如果您的模块试图导入其他不存在的东西,这不会被报告为错误,但是模块只是停止执行。所以最好改用一些自定义异常。我只是为了示例而使用 ImportError
。