代码之家  ›  专栏  ›  技术社区  ›  G S

Python:包中的“Private”模块

  •  32
  • G S  · 技术社区  · 15 年前

    我有一个包裹 mypack 带模块 mod_a mod_b 在里面。我想要包裹本身和 自由进口:

    import mypack
    import mypack.mod_a
    

    不过,我想保留 b型 我的背包

    我的第一个问题是,在Python编程中有这样的“私有”模块是公认的做法吗?

    如果是,我的第二个问题是,向客户传达这一意图的最佳方式是什么?我是否在名字前面加下划线(即。 _mod_b )? 或者声明一个子包是个好主意 private 把这些模块都放在那里?

    4 回复  |  直到 5 年前
        1
  •  50
  •   Zearin lifeisstillgood    12 年前

    我用下划线作为私有模块的前缀,以向用户传达意图。在你的情况下,这将是 mypack._mod_b

    这与PEP8建议在用Python模块包装C-extension模块时使用前导下划线命名C-extension模块的精神相同(但并不完全类似);即。, _socket socket .

        2
  •  13
  •   G S    15 年前

    我确定的解决方案是创建一个子包“private”,并将我希望隐藏的所有模块放在其中。这样他们就躲藏起来,离开了 mypack 的模块列表更清晰,更易于解析。

    在我看来,这也不是不和谐的。

        3
  •  9
  •   aterrel    15 年前

    虽然没有显式的私有关键字,但是有一个约定,即让私有函数以一个下划线开头,但是一个双前导下划线将使它成为一个下划线,这样其他人就无法从模块外部轻松调用函数。请参见下面的 PEP 8

    - _single_leading_underscore: weak "internal use" indicator.  E.g. "from M
      import *" does not import objects whose name starts with an underscore.
    
    - single_trailing_underscore_: used by convention to avoid conflicts with
      Python keyword, e.g.
    
      Tkinter.Toplevel(master, class_='ClassName')
    
    - __double_leading_underscore: when naming a class attribute, invokes name
      mangling (inside class FooBar, __boo becomes _FooBar__boo; see below).
    
    - __double_leading_and_trailing_underscore__: "magic" objects or
      attributes that live in user-controlled namespaces.  E.g. __init__,
      __import__ or __file__.  Never invent such names; only use them
      as documented.
    

    要使整个模块私有化,不要包含它 __init__.py

        4
  •  2
  •   joel DeyaEldeen    6 年前

    在这种情况下需要注意的一点是间接导入。如果在 mypack

    from mypack._mod_b import foo
    foo()
    

    然后用户可以

    from mypack import foo
    foo()
    

    别再聪明了。我建议导入为

    from mypack import _mod_b
    _mod_b.foo()
    

    from mypack import _mod_b
    

    至于实际的目录结构,您甚至可以将Jeremy的答案扩展为 _package_of_this_kind 包中的任何东西都可以有任何“访问修饰符”,用户会知道有龙

        5
  •  1
  •   Ivo van der Wijk    15 年前

    如果有人真的需要子类化或访问mod\u b,为什么要阻止他/她这样做?您可以在您的文档和模块中始终提供一个首选API,您不应该直接访问它,而是使用mypack。