如何保护我的Python代码库,让客人看不到某些模块,但这样它仍然有效?
-
22-07-2019 - |
题
我们已经开始在Python有一些专有的算法和逻辑的敏感位,我们想保密的一个新项目。我们也将有几个外地人(市民选择成员)上的代码工作。我们不能授予外部人员访问代码的小型私人位,但是我们希望公版的工作不够好他们。
说,我们的项目,富,有一个模块,bar
,一个功能,get_sauce()
。真正发生的事情get_sauce()
是秘密的,但我们希望get_sauce()
公版返回一个可以接受的,尽管不正确,结果。
我们也因此,我们可以选择谁可以访问哪些总量控制运行我们自己的Subversion服务器。
<强>符号链接强>
我首先想到的是符号链接 - 而是bar.py
的,提供bar_public.py
大家和bar_private.py
只有内部开发人员。不幸的是,创建符号链接是乏味的,手工的工作 - 特别是当有真的是大约二十几这些私有模块
更重要的是,它使颠覆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
。然后,这两个内部和外部可以from foo import bar
,并得到正确的模块,对吧?
让我们试试这个:
% 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
可以为我提供更好的解决方案或建议?
解决方案
__init__
封装的foo
方法
因此,创建一个目录名为secret
并把它放在你的私有Subversion版本库。在secret
把你的专有bar.py
。在公共__init__.py
包放入类似的foo
:
__path__.insert(0,'secret')
这将意味着谁拥有了私人仓库等等secret
目录,他们将获得专有bar.py
作为foo.bar
如secret
是在搜索路径的第一个目录的用户。对于其他用户,Python会找不到secret
,并期待在__path__
的下一个目录,因此将bar.py
加载正常foo
。
因此,这将是这个样子:
private
└── trunk/
└── secret/
└── bar.py
public
└── trunk/
├── __init__.py
└── foo/
├── __init__.py
├── bar.py
├── baz.py
└── quux.py
其他提示
使用某种形式的插件系统,并保持你的插件你的自我,但也有获取与开放代码公开发运可用的插件。
插件系统比比皆是。你可以很容易地使死的简单的人自己。如果你想要的东西更先进的,我更喜欢Zope的组件体系结构,但也有类似的setuptools entry_points选项等。
哪一个在你的情况下使用将是一个很好的第二个问题。
下面是读取文档时,我注意到一个替代的解决方案瓶:
<强>
flaskext/__init__.py
强>此文件的唯一目的是标记包作为命名空间包。这是必需的,使得从不同的PyPI封装中的多个模块可以驻留在同一Python包:
__import__('pkg_resources').declare_namespace(__name__)
如果你想知道到底发生了什么有,签这说明它是如何工作的分发或setuptools的文档。