将实现文件隐藏在包中 [英] Hiding implementation files in a package

查看:61
本文介绍了将实现文件隐藏在包中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为spellnum的模块.它可以用作命令行实用程序(具有if __name__ == '__main__':块),也可以像标准Python模块一样导入.

I have a module called spellnum. It can be used as a command-line utility (it has the if __name__ == '__main__': block) or it can be imported like a standard Python module.

模块定义了一个名为Speller的类,如下所示:

The module defines a class named Speller which looks like this:

class Speller(object):
    def __init__(self, lang="en"):
        module = __import__("spelling_" + lang)
        # use module's contents...

如您所见,类构造函数在运行时加载其他模块.这些模块(spelling_en.pyspelling_es.py等)与spellnum.py本身位于同一目录中.

As you can see, the class constructor loads other modules at runtime. Those modules (spelling_en.py, spelling_es.py, etc.) are located in the same directory as the spellnum.py itself.

spellnum.py外,还有其他具有实用程序功能和类的文件.我想隐藏这些文件,因为我不想将它们公开给用户,并且用随机文件污染Python的lib目录是一个坏主意.我所知道的唯一实现此目的的方法是创建一个程序包.

Besides spellnum.py, there are other files with utility functions and classes. I'd like to hide those files since I don't want to expose them to the user and since it's a bad idea to pollute the Python's lib directory with random files. The only way to achieve this that I know of is to create a package.

我已经为该项目设计了此布局(受此出色的教程的启发):

I've come up with this layout for the project (inspired by this great tutorial):

spellnum/                # project root
    spellnum/            # package root
        __init__.py
        spellnum.py
        spelling_en.py
        spelling_es.py
        squash.py
        # ... some other private files
    test/
        test_spellnum.py
    example.py

文件__init__.py包含一行:

from spellnum import Speller

鉴于这种新布局,必须更改用于动态模块加载的代码:

Given this new layout, the code for dynamic module loading had to be changed:

class Speller(object):
    def __init__(self, lang="en"):
        spelling_mod = "spelling_" + lang
        package = __import__("spellnum", fromlist=[spelling_mod])
        module = getattr(package, spelling_mod)
        # use module as usual

因此,使用此项目布局,a可以执行以下操作:

So, with this project layout a can do the following:

  1. example.py内成功import spellnum并将其像一个简单模块一样使用:

  1. Successfully import spellnum inside example.py and use it like a simple module:

# an excerpt from the example.py file
import spellnum

speller = spellnum.Speller(es)
# ...

在测试中

  • import spellnum并从项目根目录运行这些测试,如下所示:

  • import spellnum in the tests and run those tests from the project root like this:

    $ PYTHONPATH="`pwd`:$PYTHONPATH" python test/test_spellnum.py
    

  • 问题

    我不能直接使用新布局执行spellnum.py.当我尝试执行此操作时,它显示以下错误:

    The problem

    I cannot execute spellnum.py directly with the new layout. When I try to, it shows the following error:

    Traceback (most recent call last):
      ...
      File "spellnum/spellnum.py", line 23, in __init__
        module = getattr(package, spelling_mod)
    AttributeError: 'module' object has no attribute 'spelling_en'
    

    问题

    组织模块运行所需的所有文件的最佳方法是什么,以使用户能够从命令行和Python代码使用该模块?

    The question

    What's the best way to organize all of the files required by my module to work so that users are able to use the module both from command line and from their Python code?

    谢谢!

    推荐答案

    如何保留spellnum.py?

    spellnum.py
    spelling/
      __init__.py
      en.py
      es.py
    

    这篇关于将实现文件隐藏在包中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆