1)编写一个 Python 包
2)想要分发它
3)不想分发源代码
4)*.pyc 可被反编译>>可提取源文件!
5)dll 是标准的。
把想要隐藏的所有内容用 Cython 编写,并编译成 pyd
。这是你能够得到编译后 Python 代码的最接近方式。
此外,dll 不是标准,至少在 Python 领域中不是。它们也不具有可移植性。
CFFI 1.5版本支持Python嵌入,您可以创建一个 .dll
文件,该文件可以被Windows C应用程序使用。
main()
函数。 - Xantiumpyd
文件,就像Dikei所写的那样。但是如果你真的想保护你的代码,最好还是用C++编写重要部分。最好的方法是结合C++和Python。这个想法是:你会将python代码开放给用户进行调整,这样你就不必一遍又一遍地编译所有内容。这意味着,你会在C++中编写“核心”(这是目前最安全的解决方案),并在你的Python代码中使用那些dll
文件。这真的取决于你正在构建什么样的工具或程序以及你想如何执行它。我通常在完成一个工具或程序后创建一个执行文件(exe
,app
),但这更多是为了最终用户。这可以通过py2exe
和py2app
(都支持64位)来完成。如果你实现了解释器,则最终用户的机器不必在系统上安装Python。
pyd
文件与dll
文件相同,完全支持Python。因此,您可以正常导入您的模块。您可以在这里找到更多信息。
使用和生成pyd
文件是创建安全且可移植的Python代码的最快最简单的方法。
您还可以使用C ++编写真实的dll
文件,并使用ctypes
导入它们以使用它们(在这里是一个很好的文章,以及如何工作的Python描述)。
对Nick ODell的回答进行补充
您必须在Windows上才能使用DLL,它们不具备可移植性。
但是,以下代码是跨平台的,所有平台都支持运行时,因此可以为需要其工作的每个平台重新编译它。
Python目前还没有提供创建dll的简单工具,但可以使用C/C++完成。
首先,您需要一个编译器(Windows默认没有),特别是Cygwin、MinGW或Visual Studio。
同时也需要基本的C语言知识(因为我们将主要使用C来编码)。
您还需要包含必要的头文件,我将跳过这部分,以免变得非常冗长,并假定一切都已正确设置。
为了演示,我们将打印传统的hello world:
我们将转换为DLL的Python代码:
def foo(): print("hello world")
C代码:
#include "Python.h" // Includes everything to use the Python-C API
int foo(void); // Declare foo
int foo(void) { // Name of our function in our DLL
Py_Initialize(); // Initialise Python
PyRun_SimpleString("print('hello world')"); // Run the Python commands
return 0; // Finish execution
}
以下是嵌入Python的教程,与此相关的还有一些额外内容,但为了简洁起见,我将省略它们。
编译后,您应该会得到一个DLL文件。:)
但这还不够。您需要分发所需的任何依赖项,这意味着需要运行Python脚本的python36.dll
运行时和其他一些组件。
我的C编码不完美,如果有人发现任何改进,请评论并尽力修复。
从这个回答中,也可能可以使用C#,因为C#可以创建DLL文件,并且您可以从C#调用Python函数:如何在C#中调用Python脚本中的特定方法?
这是我的想法,可能会起作用。我不知道那是否有效。
1.创建你的*.py
文件。
2.将它们重命名为*.pyx
3.使用Cython将它们转换成*.c
文件
4.将*.c
编译成*.dll
文件。
但我不建议你这样做,因为它只能在Windows平台上运行。
pip install pyinstaller
,步骤2. 新建一个Python文件,命名为code.py
。步骤3. 编写一些代码,例如print("Hello World")
。步骤4. 在相同的位置打开命令提示符,并输入pyinstaller code.py
,然后按回车键。最后一步在相同的位置中将会创建两个文件夹,名称为build, dist
。在dist文件夹中有一个名为code
的文件夹,在该文件夹中有一个exe文件code.exe
以及所需的.dll文件。 - Adnan Mohib如果您的唯一目标是隐藏源代码,那么更简单的方法是将代码编译为可执行文件(例如使用PyInstaller),并使用具有可读源代码的模块进行通信。 注意:您可能需要更多的转换函数,就像这个例子中所示。 例子: 模块:
import subprocess
import codecs
def _encode_str(str):
encoded=str.encode("utf-32","surrogatepass")
return codecs.encode(encoded,"base64").replace(b"\n",b"")
def _decode_str(b64):
return codecs.decode(b64,"base64").decode("utf-32","surrogatepass")
def strlen(s:str):#return length of str;int
proc=subprocess.Popen(["path_to_your_exe.exe","strlen",_encode_str(str).decode("ascii")],stdout=subprocess.PIPE)
return int(proc.stdout.read())
def random_char_from_string(str):
proc=subprocess.Popen(["path_to_your_exe.exe","randchr",_encode_str(str).decode("ascii")],stdout=subprocess.PIPE)
return _decode_str(proc.stdout.read())
可执行文件:
import sys
import codecs
import random
def _encode_str(str):
encoded=str.encode("utf-32","surrogatepass")
return codecs.encode(encoded,"base64").replace(b"\n",b"")
def _decode_str(b64):
return codecs.decode(b64,"base64").decode("utf-32","surrogatepass")
command=sys.argv[1]
if command=="strlen":
s=_decode_str(sys.argv[2].encode("ascii"))
print(len(str))
if command=="randchr":
s_decode_str(sys.argv[2].encode("ascii"))
print(_encode_str(random.choice(s)).decode("ascii"))