如何保护我的Python代码库,以使访客看不到某些模块,但仍然可以使用?

我们正在Python中启动一个新项目,其中包含一些专有算法和我们想保密的敏感逻辑部分.我们还将有一些局外人(部分公众人士)来编写该代码.我们无法授予局外人访问较小的私人代码段的权限,但是我们希望公开版本的代码足以让他们使用.

假设我们的项目Foo有一个带有一个函数get_sauce()的模块bar. get_sauce()中真正发生的事情是秘密的,但是我们希望get_sauce()的公共版本返回可接受的(尽管不正确)结果.

我们还运行自己的Subversion服务器,因此我们可以完全控制谁可以访问什么.

符号链接

我的第一个想法是符号链接-而不是bar.py,向所有人提供bar_public.py,仅向内部开发人员提供bar_private.py.不幸的是,创建符号链接是繁琐的手动工作,尤其是当这些私有模块确实要有大约二十个时.

更重要的是,这使Subversion authz文件的管理变得困难,因为必须在服务器上添加要保护异常的每个模块.有人可能会忘记执行此操作,并且不小心检查了机密信息……然后,该模块位于存储库中,我们必须在没有存储库的情况下重建存储库,并希望外来者不要同时下载它.

多个存储库

下一个想法是要有两个存储库:

private
└── trunk/
    ├── __init__.py
    └── foo/
        ├── __init__.py
        └── bar.py
public
└── trunk/
    ├── __init__.py
    └── foo/
        ├── __init__.py
        ├── bar.py
        ├── baz.py
        └── quux.py

这个想法是,只有内部开发人员才能签出private /和public /.内部开发人员将设置其PYTHONPATH = private / trunk:public / trunk,但其他所有人都将设置PYTHONPATH = public / trunk.然后,内部人员和外部人员都可以从foo导入栏中获取正确的模块,对吗?

让我们尝试一下:

% PYTHONPATH=private/trunk:public/trunk python
Python 2.5.1
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo.bar
>>> foo.bar.sauce()
'a private bar'
>>> import foo.quux
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named quux

我不是Python专家,但似乎Python已经下定决心要对模块foo进行搜索,并进行相关的搜索:

>>> foo
<module 'foo' from '/path/to/private/trunk/foo/__init__.py'>

甚至不删除foo都可以帮助:

>>> import sys
>>> del foo
>>> del sys.modules['foo']
>>> import foo.quux
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named quux

您能为我提供更好的解决方案或建议吗?

解决方法:

In the __init__ method of the foo package you can change __path__ to make it look for its modules in other directories.

因此,创建一个名为secret的目录,并将其放入您的私有Subversion存储库中.秘密地放下您专有的bar.py.在公共foo包的__init__.py中,输入以下内容:

__path__.insert(0,'secret')

这将意味着对于拥有私有存储库的用户,因此,他们将使用秘密目录将他们的专有bar.py作为foo.bar获得,因为secret是搜索路径中的第一个目录.对于其他用户,Python不会发现秘密,它们将成为__path__中的下一个目录,因此将从foo加载普通的bar.py.

因此它将看起来像这样:

   private
    └── trunk/
        └── secret/
            └── bar.py
    public
    └── trunk/
        ├── __init__.py
        └── foo/
            ├── __init__.py
            ├── bar.py
            ├── baz.py
            └── quux.py
上一篇:java – 传统文件夹层次结构中的TypeScript类


下一篇:php – 我可以在字符串中存储逻辑比较吗?