किसी स्क्रिप्ट को दूसरी स्क्रिप्ट से कॉल करने का सबसे अच्छा तरीका क्या है?


307

मेरे पास एक स्क्रिप्ट है जिसका नाम test1.py है जो किसी मॉड्यूल में नहीं है। इसमें सिर्फ कोड होता है जिसे स्क्रिप्ट के चलने पर निष्पादित करना चाहिए। कोई कार्य, कक्षाएं, विधियां आदि नहीं हैं। मेरे पास एक और स्क्रिप्ट है जो एक सेवा के रूप में चलती है। मैं सेवा के रूप में चल रहे स्क्रिप्ट से test1.py कॉल करना चाहता हूं।

उदाहरण के लिए:

फ़ाइल test1.py

print "I am a test"
print "see! I do nothing productive."

फ़ाइल सेवा

# Lots of stuff here
test1.py # do whatever is in test1.py

मुझे एक विधि की जानकारी है जो फ़ाइल खोल रही है, सामग्री को पढ़ रही है, और मूल रूप से इसे विकसित कर रही है। मुझे लगता है कि ऐसा करने का एक बेहतर तरीका है। या कम से कम मैं उम्मीद कर सकता हूं।


42
बेहतर तरीका यह है कि तरीकों और कक्षाओं को लिखें और उनका उपयोग करें
आमिर


3
किसी ने runpy.run_moduleअभी तक एक जवाब पोस्ट नहीं किया है ?!
अरन-फे

जवाबों:


279

ऐसा करने का सामान्य तरीका कुछ निम्नलिखित है।

test1.py

def some_func():
    print 'in test 1, unproductive'

if __name__ == '__main__':
    # test1.py executed as script
    # do something
    some_func()

service.py

import test1

def service_func():
    print 'service func'

if __name__ == '__main__':
    # service.py executed as script
    # do something
    service_func()
    test1.some_func()

44
क्या होगा अगर test1.pyकुछ दूर की निर्देशिका में स्थित है?
इवगेनी सर्गेव


18
हालांकि यह वास्तव में इस सवाल का जवाब नहीं देता है, यह करता है? आप पूरी स्क्रिप्ट निष्पादित नहीं कर रहे हैं, आप अपने द्वारा आयात की जाने वाली स्क्रिप्ट के कुछ कार्यों को निष्पादित कर रहे हैं।
gented

2
@GennaroTedesco: आप गलत हैं। import test1में service.pyवास्तव में अमल करता है पूरी स्क्रिप्ट (जो केवल परिभाषित करता है some_func()के बाद से __name__ == '__main__'किया जाएगा Falseकि मामले में)। ऐसा लगता है जैसे सभी ओपी करना चाहते हैं। यह उत्तर उससे आगे निकल जाता है, लेकिन निश्चित रूप से प्रश्न का उत्तर देता है - और फिर कुछ।
मार्टीन्यू

2
यदि कहें, test1.pyतो फ़ंक्शन की परिभाषा नहीं थी some_func()(लेकिन उदाहरण के लिए कोड की कुछ पंक्तियाँ, उदाहरण के लिए print("hello")) तो आपका कोड काम नहीं करेगा। इस विशेष उदाहरण में यह काम करता है क्योंकि आप अनिवार्य रूप से एक बाहरी फ़ंक्शन आयात कर रहे हैं जिसे आप बाद में वापस बुला रहे हैं।
gented

144

इसका उपयोग करके पायथन 2 में संभव है

execfile("test2.py")

यदि आपके मामले में महत्वपूर्ण है, तो नामस्थान की हैंडलिंग के लिए दस्तावेज़ देखें ।

पायथन 3 में, यह प्रयोग संभव है (@fantastory के लिए धन्यवाद)

exec(open("test2.py").read())

हालांकि, आपको एक अलग दृष्टिकोण का उपयोग करने पर विचार करना चाहिए; आपका विचार (जो मैं देख सकता हूं) बहुत साफ नहीं दिखता है।


9
सीधे-सीधे मुझे अजगर 32 में क्या चाहिए, यह निष्पादित है (खुला ('test2.py') पढ़ें। ())
फंतासी

8
यह दृष्टिकोण कॉलिंग नेमस्पेस की स्क्रिप्ट को निष्पादित करता है। :)
dmvianna

6
स्क्रिप्ट में कमांड-लाइन तर्क पारित करने के लिए, आप sys.argvसूची को संपादित कर सकते हैं ।
18

1
पायथन 3 समकक्षों पर अधिक व्यापक उपचार: stackoverflow.com/questions/436198/…
जॉन वाई

2
यह तर्क स्वीकार नहीं करता है (PY फ़ाइल में पारित होने के लिए)!
अपोस्टोलोस

70

दूसरा रास्ता:

फ़ाइल test1.py

print "test1.py"

फ़ाइल सेवा थिंकपैड:

import subprocess

subprocess.call("test1.py", shell=True)

इस पद्धति का लाभ यह है कि आपको अपने सभी कोड को एक सबरूटीन में डालने के लिए एक मौजूदा पायथन स्क्रिप्ट को संपादित करने की आवश्यकता नहीं है।

प्रलेखन: पायथन 2 , पायथन 3


7
मुझे subprocess.call("./test1.py", shell=True)इसे काम करने के लिए उपयोग करना था
asmaier

5
shell=Trueजब तक यह आवश्यक न हो उपयोग न करें ।
पायोत्र डोब्रोगोस्ट 10

2
@PiotrDobrogost - क्या आप निर्दिष्ट कर सकते हैं कि कौन सी परिस्थितियाँ इसे आवश्यक बनाती हैं?
sancho.s ReinstateMonicaCellio

7
यह एक विशिष्ट यूनिक्स पर काम नहीं करेगा जहां मौजूदा निर्देशिका पथ में नहीं है। test1.pyनिष्पादन योग्य होना चाहिए और शेबंग लाइन ( #!/usr/bin/env python) होनी चाहिए और आपको पूर्ण पथ निर्दिष्ट करना चाहिए या आपको निष्पादन योग्य स्वयं प्रदान करने की आवश्यकता है: call([sys.executable, os.path.join(get_script_dir(), 'test1.py')])जहां get_script_dir()यहां परिभाषित किया गया है
शाम

5
या subprocess.call(['python', 'test1.py'])
बिग मैक्लेरिजह्यूज

21

यदि आप चाहते हैं कि test1.py उसी कार्यक्षमता के साथ निष्पादन योग्य बना रहे जब उसे सेवा-सेवा के अंदर कहा जाता है, तो कुछ ऐसा करें:

test1.py

def main():
    print "I am a test"
    print "see! I do nothing productive."

if __name__ == "__main__":
    main()

service.py

import test1
# lots of stuff here
test1.main() # do whatever is in test1.py

3
यदि आपके पास रनटाइम पैरामीटर हैं तो क्या होगा?
गेब्रियल फेयर

13
import os

os.system("python myOtherScript.py arg1 arg2 arg3")  

ओएस का उपयोग करके आप अपने टर्मिनल पर सीधे कॉल कर सकते हैं। यदि आप और भी अधिक विशिष्ट होना चाहते हैं, तो आप अपने इनपुट स्ट्रिंग को स्थानीय चर के साथ बदल सकते हैं, अर्थात।

command = 'python myOtherScript.py ' + sys.argv[1] + ' ' + sys.argv[2]
os.system(command)

कॉल से os.systemबचा जाना चाहिए, आप किसी भी वर्ग से ऐसा कर सकते हैंPopen, Call,
user1767754

से अजगर प्रलेखन : उपप्रक्रिया मॉड्यूल नई प्रक्रियाओं को उत्पन्न करने और उनके परिणामों को पुन: प्राप्त करने के लिए और अधिक शक्तिशाली सुविधाएं प्रदान करता है; इस फ़ंक्शन का उपयोग करने के लिए उस मॉड्यूल का उपयोग करना बेहतर होता है।
बजे बिग मैक्लेरजैग

12

आपको ऐसा नहीं करना चाहिए। इसके बजाय, करें:

test1.py:

 def print_test():
      print "I am a test"
      print "see! I do nothing productive."

service.py

#near the top
from test1 import print_test
#lots of stuff here
print_test()

1
जब आप test1 आयात करते हैं तो यह कैसे पता चलता है कि फ़ाइल कहाँ है? क्या इसे उसी निर्देशिका में होना चाहिए? अगर नहीं तो क्या?
NULL.Dude

8

का प्रयोग करें import test11 उपयोग के लिए - यह स्क्रिप्ट को निष्पादित करेंगे। बाद के इनवोकेशन के लिए, स्क्रिप्ट को एक आयातित मॉड्यूल के रूप में समझें, और reload(test1)विधि को कॉल करें ।

जब reload(module)निष्पादित किया जाता है:

  • पायथन मॉड्यूल के कोड को फिर से जोड़ दिया जाता है और मॉड्यूल स्तर के कोड को फिर से जोड़ दिया जाता है , जो वस्तुओं के एक नए सेट को परिभाषित करता है जो मॉड्यूल के शब्दकोश में नामों से बंधा होता है। विस्तार मॉड्यूल के init फ़ंक्शन को नहीं कहा जाता है

sys.modulesउचित कार्रवाई के आह्वान के लिए एक सरल जांच का उपयोग किया जा सकता है। स्क्रिप्ट नाम को एक स्ट्रिंग ( 'test1') के रूप में संदर्भित रखने के लिए, ' आयात ()' बिल्डिन का उपयोग करें।

import sys
if sys.modules.has_key['test1']:
    reload(sys.modules['test1'])
else:
    __import__('test1')

3
reloadपायथन 3 में चला गया है
पिओटर डॉब्रोगोस्ट 10

1
एक मॉड्यूल का आयात यह जैसे चल रहा है के बराबर नहीं है, पर विचार if __name__ == "__main__":गार्ड। अन्य अधिक सूक्ष्म अंतर हो सकते हैं। वैश्विक स्तर पर मनमाना कोड न छोड़ें। इसे किसी फ़ंक्शन में रखें और आयात के बाद कॉल करें जैसा कि इसके बजाय स्वीकृत उत्तर में सुझाया गया है
jfs


3

सिर्फ test1 आयात क्यों नहीं? हर पाइथन स्क्रिप्ट एक मॉड्यूल है। एक बेहतर तरीका यह होगा कि एक फ़ंक्शन होना चाहिए जैसे कि test1.py में मुख्य / रन, टेस्ट 1 आयात करें और test1.main () चलाएं। या आप उपप्रोसेस के रूप में test1.py को निष्पादित कर सकते हैं।


3

जैसा कि यह पहले ही उल्लेख किया गया है, runpyवर्तमान स्क्रिप्ट से अन्य स्क्रिप्ट या मॉड्यूल चलाने का एक अच्छा तरीका है।

वैसे, ट्रैसर या डिबगर के लिए ऐसा करना काफी सामान्य है, और ऐसी परिस्थितियों में फ़ाइल को सीधे आयात करना या फ़ाइल को सबप्रोसेस में चलाना जैसे तरीके आमतौर पर काम नहीं करते हैं।

इसे execकोड चलाने के लिए उपयोग करने के लिए भी ध्यान देने की आवश्यकता है । आपको run_globalsआयात त्रुटि या कुछ अन्य मुद्दों से बचने के लिए उचित प्रदान करना होगा। विवरण के runpy._run_codeलिए देखें।


0

यह subprocessपुस्तकालय के साथ एक उदाहरण है:

import subprocess

python_version = '3'
path_to_run = './'
py_name = '__main__.py'

# args = [f"python{python_version}", f"{path_to_run}{py_name}"]  # Avaible in python3
args = ["python{}".format(python_version), "{}{}".format(path_to_run, py_name)]

res = subprocess.Popen(args, stdout=subprocess.PIPE)
output, error_ = res.communicate()

if not error_:
    print(output)
else:
    print(error_)

1
पायथन को पायथन के उपप्रकार के रूप में चलाना लगभग कभी भी सही समाधान नहीं है। यदि आप एक उपप्रकार के साथ जाते हैं, तो आपको Popenतब तक बचना चाहिए जब तक कि उच्च-स्तरीय फ़ंक्शन वास्तव में वह नहीं कर सकते जो आप चाहते हैं। इस मामले में, check_callया runआप की जरूरत है और अधिक सब कुछ होगा, अपने स्वयं के कोड में काफी कम पाइपलाइन के साथ।
ट्रिपल

0

यह प्रक्रिया कुछ हद तक गैर-रूढ़िवादी है, लेकिन सभी अजगर संस्करणों में काम करेगी,

मान लीजिए कि आप 'अगर' स्थिति के अंदर 'सिफारिश' नामक स्क्रिप्ट निष्पादित करना चाहते हैं, तो उपयोग करें,

if condition:
       import recommend

तकनीक अलग है, लेकिन काम करती है!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.