2012-10-19 15 views
5

我分配具有此結構的包:在Python distutils中從setup.py查找腳本目錄的正確方法?

mymodule: 
    mymodule/__init__.py 
    mymodule/code.py 
    scripts/script1.py 
    scripts/script2.py 

mymodule子目錄的mymodule包含代碼和scripts子目錄包含的腳本,應該是由用戶執行。

setup.py描述包安裝,我用:

scripts=['myscripts/script1.py'] 

要指定腳本應該去。在安裝期間,他們通常會進入某個平臺/用戶特定的bin目錄。我在mymodule/mymodule中的代碼需要調用腳本。然後找到這些腳本的完整路徑的正確方法是什麼?理想情況下,他們應該是用戶的路徑上,在這一點上,所以如果我想將它們從殼叫喚,我應該能夠做到:

os.system('script1.py args') 

但我希望通過它的絕對路徑調用腳本,而不是依賴於特定平臺的bin目錄正對PATH,如:

# get the directory where the scripts reside in current installation 
scripts_dir = get_scripts_dir() 
script1_path = os.path.join(scripts_dir, "script1.py") 
os.system("%s args" %(script1_path)) 

如何才能做到這一點?謝謝。

編輯刪除腳本以外的代碼對我來說不是一個實際的解決方案。原因是我分配任務到集羣系統和我平時就是這個樣子的方法:想象你有一組要運行的任務。我有一個腳本將所有任務作爲輸入,然後調用另一個腳本,該腳本只在給定任務上運行。喜歡的東西:

main.py: 
for task in tasks: 
    cmd = "python script.py %s" %(task) 
    execute_on_system(cmd) 

所以main.py需要知道script.py是,因爲它需要通過execute_on_system一個命令來執行。

+0

相關:[確定distutils的數據的位置文件編程在Python?](http://stackoverflow.com/q/8628495/95735 ) –

+0

如何'execute_on_system()'什麼樣子的? –

+0

@PiotrDobrogost:'execute_on_system'作爲輸入對應於外殼命令的字符串。然後,它創建了一個名爲臨時文件'cmd.sh'和它把命令中,陳述工作應該如何運行(具體到集羣系統在用戶的系統上使用)必要的前綴一起 - 例如什麼隊列中的作業應該進入,等等。然後它需要這個腳本,'cmd.sh'並以系統特定的方式執行它,例如通過做:'os.system(「qsub cmd。sh「) – user248237dfsf

回答

3

我想你應該組織你的代碼,這樣你就不需要從你的代碼中調用腳本。將您需要的代碼從腳本移動到您的包中,然後您可以從腳本和代碼中調用此代碼。

+0

我喜歡這個想法,但實際上它不適用於我,看到即將到來的編輯 – user248237dfsf

+0

我什麼都看不到在你的工作流程中阻止將一些代碼從腳本移動到包中 –

+0

我需要能夠創建一個調用Python腳本的命令,它是我的包的一部分,像「python myscript.py someargs」,因此,我需要知道* where * myscript.py的居住地......甚至myscript.py是軟件包的一部分,而不是在腳本目錄中,我仍然需要使用'__file__'這樣的黑客來找出腳本的位置。這從設計角度來看是可取的而不是試圖找出腳本目錄在哪裏?這兩種解決方案看起來都不盡人意 – user248237dfsf

1

我的使用情況,這是檢查我的腳本安裝到目錄是在用戶的路徑,並給予警告,如果不是(因爲它往往是不在路徑如果與--user安裝)。這裏是我想出瞭解決方案:

from setuptools.command.easy_install import easy_install 

class my_easy_install(easy_install): 

    # Match the call signature of the easy_install version. 
    def write_script(self, script_name, contents, mode="t", *ignored): 

     # Run the normal version 
     easy_install.write_script(self, script_name, contents, mode, *ignored) 

     # Save the script install directory in the distribution object. 
     # This is the same thing that is returned by the setup function. 
     self.distribution.script_install_dir = self.script_dir 

... 

dist = setup(..., 
      cmdclass = {'build_ext': my_builder, # I also have one of these. 
         'easy_install': my_easy_install, 
         }, 
      ) 

if dist.script_install_dir not in os.environ['PATH'].split(':'): 
    # Give a sensible warning message... 

我應該指出,這是setuptools的。如果您使用的distutils,那麼解決的辦法是相似,但稍有不同:

from distutils.command.install_scripts import install_scripts 

class my_install_scripts(install_scripts): # For distutils 
    def run(self): 
     install_scripts.run(self) 
     self.distribution.script_install_dir = self.install_dir 

dist = setup(..., 
      cmdclass = {'build_ext': my_builder, 
         'install_scripts': my_install_scripts, 
         }, 
      ) 
相關問題