我们正在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
您能为我提供更好的解决方案或建议吗?
解决方法:
因此,创建一个名为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