2010-08-09 57 views
8

我想從distutils創建一個只有字節碼的發行版(我真的不知道,我知道我在做什麼)。使用setuptools和bdist_egg命令,您可以簡單地提供--exclude-source參數。不幸的是,標準命令沒有這樣的選項。如何從distutils二進制發行版中去除源代碼?

  • 是否有一種簡單的方法在tar.gz,zip,rpm或deb創建之前去除源文件。
  • 是否有一個相對乾淨的每命令的方式來做到這一點(例如只是爲tar.gz或zip)。
+1

非常相似:http://stackoverflow.com/questions/261638/how-do-i-protect-python-code編譯的python文件(pyc/pyo)對於反編譯非常簡單。 – 2010-08-09 13:31:04

+8

@Nick:不是。我根本沒有提到保護,而且這個問題沒有提到distutils。顯然python字節碼很容易分析,現在怎麼樣解決我實際問到的問題? – Draemon 2010-08-09 13:57:48

+0

如果你只是想從zip中刪除所有* .py文件:'7z d archive.zip * .py -r' – 2010-08-09 14:24:02

回答

11

distutils「build_py」命令是重要的命令,因爲它被所有創建分發的命令(間接)重用。如果忽略byte_compile(文件)的方法,是這樣的:

try: 
    from setuptools.command.build_py import build_py 
except ImportError: 
    from distutils.command.build_py import build_py 

class build_py(build_py) 
    def byte_compile(self, files): 
     super(build_py, self).byte_compile(files) 
     for file in files: 
      if file.endswith('.py'): 
       os.unlink(file) 

setup(
    ... 
    cmdclass = dict(build_py=build_py), 
    ... 
) 

你應該能夠讓這個源文件是從之前他們複製到「安裝」目錄(編譯樹中刪除當bdist命令調用它們時,它是一個臨時目錄)。

注:我沒有測試過這個代碼;因人而異。

+0

+1。這正是我所希望的。我沒有意識到有一個共同的build_py我可以掛鉤。我會試試看看是否需要調整。 – Draemon 2010-08-10 09:47:06

+1

+1但是在Python 2.7.6上它不起作用,因爲build_py是一箇舊式類,不能和super()一起使用。我使用'build_py.byte_compile(self,files)'代替。 (我也重命名了build_py類,所以它不會打開導入的build_py。) – 2014-07-28 18:08:45

1

試試這個:

from distutils.command.install_lib import install_lib 

class install_lib(install_lib, object): 

    """ Class to overload install_lib so we remove .py files from the resulting 
    RPM """ 

    def run(self): 

     """ Overload the run method and remove all .py files after compilation 
     """ 

     super(install_lib, self).run() 
     for filename in self.install(): 
      if filename.endswith('.py'): 
       os.unlink(filename) 

    def get_outputs(self): 

     """ Overload the get_outputs method and remove any .py entries in the 
     file list """ 

     filenames = super(install_lib, self).get_outputs() 
     return [filename for filename in filenames 
       if not filename.endswith('.py')] 
1

也許一個完整的工作代碼在這裏:)

try: 
     from setuptools.command.build_py import build_py 
except ImportError: 
     from distutils.command.build_py import build_py 

import os 
import py_compile 

class custom_build_pyc(build_py): 
    def byte_compile(self, files): 
     for file in files: 
      if file.endswith('.py'): 
       py_compile.compile(file) 
       os.unlink(file) 
.... 
setup(
    name= 'sample project', 
    cmdclass = dict(build_py=custom_build_pyc), 
.... 
0

「的標準命令沒有這樣的選擇」?

您是否安裝了最新版本的setuptools?你有沒有寫過setup.py文件?

如果是這樣,這應該工作:python setup.py bdist_egg --exclude-source-files

+0

我在問題中注意到我設法爲bdist_egg執行此操作。這是其他產出(例如拉鍊)缺乏選擇。 – Draemon 2016-09-22 09:44:41