简体   繁体   English

如何使用__all__阻止用户在子模块中显示x时从子模块中导入x

[英]How do I prevent users from importing x from a submodule when it exposed in the parent using __all__

Consider the following scenario: 请考虑以下情形:

  • You have a module M defined in m.py containing a function f . 您在m.py中定义了m.py包含函数f的模块M

    It can be called like this: 它可以像这样调用:

     import M; Mf() 
  • The module grows to a size where it is impractical to have in a single file. 模块增长到一个大小,在单个文件中是不切实际的。 You split M up into submodules MX , MY , MZ and put the following in M/__init__.py : 您将M拆分为子模块MXMYMZ并将以下内容放在M/__init__.py

     from .X import * from .Y import * from .Z import * __all__ = ["f"] 

    The original code still works: 原始代码仍然有效:

     import M; Mf() 

However, new consumers of the code may mistakenly access the submodule directly: 但是,代码的新消费者可能会错误地直接访问子模块:

import M.X;
M.X.f()

I would like to prevent this, such that all code is still consistently addressing M directly, and not any of the submodules. 我想阻止这种情况,这样所有代码仍然可以直接解决M,而不是任何子模块。

The submodules are for the benefit of internal code organisation, and referencing M leaves the possibility of easy reorganisation in the future. 子模块是为了内部代码组织的利益,并且引用M使得将来可以轻松重组。

One option would be to name the submodules _X , _Y , and _Z to communicate that they are internal. 一种选择是命名子模块_X_Y_Z以传达它们是内部的。 Is that the recommended approach? 这是推荐的方法吗?

One option would be to name the submodules _X, _Y, and _Z to communicate that they are internal. 一种选择是命名子模块_X,_Y和_Z以传达它们是内部的。 Is that the recommended approach? 这是推荐的方法吗?

As you don't want people to access MX, you will need to move the X.py module so it is no longer available as MX You could delete it as Kaie suggests, but ugh. 由于您不希望人们访问MX,您需要移动X.py模块,使其不再像MX那样可以将其删除为Kaie建议,但是呃。 Therefore yes, your suggestion is the recommended approach. 因此,是的,您的建议是推荐的方法。

  1. Move M/X.py to M/_X.py M/X.py移动到M/_X.py

  2. In M/__init__.py have the line from ._X import f M/__init__.pyfrom ._X import f的行

As others have suggested, it shouldn't really be a problem that people can access the code and it's habits of programming in a language with stronger encapsulation seeping into your Python designs. 正如其他人所建议的那样,人们可以访问代码并不一定是一个问题,而且习惯于使用一种渗透到Python设计中的更强大的封装语言进行编程。

The submodules are for the benefit of internal code organisation, and referencing M leaves the possibility of easy reorganisation in the future. 子模块是为了内部代码组织的利益,并且引用M使得将来可以轻松重组。

Yes this is a concern I had when coming from C and C++ and dealing with ABIs all day. 是的,这是我在使用C和C ++并整天处理ABI时所关注的问题。 But it's often not an issue if the code is small and well tested enough. 但是,如果代码很小且经过充分测试,通常不会出现问题。 And this is the kind of thing that you can trivially fix later. 这是你以后可以轻易解决的问题。 If you one day decide to reorganize the code to have X as _X then I'm sure Jenkins can tell you what else needs to be updated. 如果你有一天决定重新组织代码让X_X那么我肯定Jenkins可以告诉你还需要更新什么。 :) :)

There is a way, but I don't think you gonna like it: 有一种方法,但我不认为你会喜欢它:

# M/__init__.py

from .X import *
del X
__all__ = ["x"]

You can still do import MX , but will throw Error when using it. 您仍然可以import MX ,但在使用时会抛出Error。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 python 从更新中排除 git 子模块? - How do I exclude a git submodule from update using python? 在python中,如何通过父模块或顶级模块访问子类的实例以及子模块 - In python how do I access an instance of a class from a parent or top-level module from withing a submodule 如何在模块中定义一个 `from ... import *' api 与 __all__ 分开? - How to define a `from … import *' api seperate from __all__ in a module? 如何使子模块的类在父模块的命名空间中可用? - How do I make classes from a submodule available in a parent module's namespace? 如何避免导入模块导入? 你能在运行时动态生成 __all__ 吗? - How do you avoid importing a modules imports? Can you dynamically generate `__all__` at runtime? 为什么即使未定义__all__,pkg import *最终导入模块? - Why does from pkg import * end up importing a module even if __all__ is not defined? 与__init__.py混淆并从子模块导入父模块中的类 - Confusion with __init__.py and importing classes in parent module from submodule 在 Python 中导入模块时,何时使用 __all__? - When is __all__ used while importing a module in Python? 为什么Python 3中的__all__缺少NoReturn - Why is NoReturn missing from __all__ in Python 3 子类化 TestCase 时,如何防止 Django 在父类上运行单元测试? - How do I prevent Django from running unit tests on parent class when subclassing TestCase?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM