অন্য স্ক্রিপ্ট থেকে স্ক্রিপ্ট কল করার সবচেয়ে ভাল উপায় কী?


307

আমার কাছে test1.py নামের একটি স্ক্রিপ্ট রয়েছে যা কোনও মডিউলটিতে নেই। এটিতে কেবল কোড রয়েছে যা স্ক্রিপ্টটি নিজে চালিত হলে কার্যকর করা উচিত। এখানে কোন ফাংশন, ক্লাস, পদ্ধতি ইত্যাদি নেই I আমার কাছে আরও একটি স্ক্রিপ্ট রয়েছে যা একটি পরিষেবা হিসাবে চলে runs আমি পরিষেবা হিসাবে চলমান স্ক্রিপ্ট থেকে 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কোনও দূরবর্তী ডিরেক্টরিতে অবস্থিত হয় তবে কী হবে ?
এভেজেনি সার্জিভ

3
@EvgeniSergeev দেখুন stackoverflow.com/questions/67631/...
Evgeni Sergeev

18
এটি সত্যই যদিও প্রশ্নের উত্তর দেয় না, তাই না? আপনি পুরো স্ক্রিপ্টটি কার্যকর করছেন না, আপনি যে আমদানিটি আমদানি করছেন সেই স্ক্রিপ্টের মধ্যে থেকে কিছু ফাংশন সম্পাদন করছেন।
শে

2
@ জেনারো টেডেসকো: আপনি ভুল করেছেন। import test1মধ্যে service.pyপ্রকৃতপক্ষে চালানো নেই পুরো স্ক্রিপ্ট (যা শুধুমাত্র সংজ্ঞায়িত some_func()যেহেতু __name__ == '__main__'হতে হবে Falseযে ক্ষেত্রে)। এটি সমস্ত ওপি করতে চায় বলে মনে হচ্ছে। এই উত্তরটি অতিক্রম করে যায় তবে অবশ্যই প্রশ্নের উত্তর দেয় does এবং তারপরে কিছু।
মার্টিনো

2
যদি, বলুন, test1.pyফাংশনটির সংজ্ঞাটি না থাকলে some_func()(উদাহরণস্বরূপ কেবল কোডের কয়েকটি লাইন print("hello")) তবে আপনার কোডটি কাজ করবে না। এই বিশেষ উদাহরণে এটি কাজ করে কারণ আপনি মূলত একটি বাহ্যিক ফাংশন আমদানি করছেন যা পরে আপনি কল করছেন।
জেন্ট করা হয়েছে

144

পাইথন 2 ব্যবহার করে এটি সম্ভব

execfile("test2.py")

আপনার ক্ষেত্রে গুরুত্বপূর্ণ হলে নেমস্পেসগুলি পরিচালনা করার জন্য ডকুমেন্টেশন দেখুন ।

পাইথন 3 এ, এটি ব্যবহার করা সম্ভব (@ ফ্যান্টাস্টোরিয়াকে ধন্যবাদ)

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

যাইহোক, আপনি একটি ভিন্ন পদ্ধতির ব্যবহার বিবেচনা করা উচিত; আপনার ধারণা (যা আমি দেখতে পাচ্ছি) খুব পরিষ্কার দেখাচ্ছে না।


9
সরাসরি আমি পাইথন 32 যা প্রয়োজন তা Exec আছে (খোলা ( 'test2.py') পড়া ()।)
fantastory

8
এই পদ্ধতির কলিং নেমস্পেসের মধ্যে স্ক্রিপ্টগুলি কার্যকর করে। :)
ডিএমভিয়ান

6
স্ক্রিপ্টে কমান্ড-লাইন আর্গুমেন্টগুলি পাস করার জন্য, আপনি sys.argvতালিকা সম্পাদনা করতে পারেন ।
jfs

1
পাইথন 3 সমতুল্য বিষয়ে আরও ব্যাপক চিকিত্সা: স্ট্যাকওভারফ্লো.com
জন ওয়াই

2
এটি আর্গুমেন্ট গ্রহণ করে না (পিওয়াই ফাইলে পাস করার জন্য)!
অ্যাপস্টোলোস

70

অন্য উপায়:

ফাইল পরীক্ষা 1.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এটি প্রয়োজনীয় না হলে ব্যবহার করবেন না ।
পাইওটর ডব্রোগস্ট

2
@ পাইওটারডব্রোগস্ট - আপনি কি নির্দিষ্ট করতে পারবেন যে কোন পরিস্থিতিতে এটি প্রয়োজনীয় হবে?
sancho.s পুনরায় ইনস্টল করুন মনিকাসেলিও

7
এটি এমন সাধারণ ইউনিক্সে কাজ করবে না যেখানে বর্তমান ডিরেক্টরিটি PATH তে নেই। test1.pyএক্সিকিউটেবল হতে হবে এবং শেবাং লাইন থাকতে হবে ( #!/usr/bin/env python) এবং আপনার পুরো পথটি নির্দিষ্ট করা উচিত বা আপনাকে এক্সিকিউটিয়েবল নিজেই সরবরাহ করতে হবে: call([sys.executable, os.path.join(get_script_dir(), 'test1.py')])যেখানে get_script_dir()এখানে সংজ্ঞায়িত করা হয়েছে
jfs

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

থেকে পাইথন ডকুমেন্টেশন : subprocess মডিউল নতুন প্রসেস ডিম ছাড়ার এবং তাদের ফলাফল পুনরুদ্ধারের জন্য আরো শক্তিশালী সুবিধা প্রদান করে; এই ফাংশনটি ব্যবহার করার জন্য সেই মডিউলটি ব্যবহার করা ভাল।
বড় ম্যাকলার্জহিউজ

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
আপনি যখন টেস্ট 1 আমদানি করবেন তখন ফাইলটি কোথায় আছে তা কীভাবে জানবে? এটি একই ডিরেক্টরিতে থাকতে হবে? যদি তা না হয়?
NULL.Dude

8

ব্যবহারের import test11st ব্যবহারের জন্য - এটা স্ক্রিপ্ট চালানো হবে। পরবর্তী অনুরোধগুলির জন্য, স্ক্রিপ্টটিকে আমদানি করা মডিউল হিসাবে বিবেচনা করুন এবং reload(test1)পদ্ধতিটি কল করুন ।

কখন reload(module)মৃত্যুদন্ড কার্যকর করা হয়:

  • পাইথন মডিউলগুলির কোডটি পুনরায় সংযুক্ত করা হয় এবং মডিউল-স্তরের কোডটি পুনরায় সাজানো হয় , মডিউলের অভিধানে নামের সাথে আবদ্ধ এমন একটি নতুন সেটকে সংজ্ঞায়িত করে। এক্সটেনশন মডিউলগুলির আরআর ফাংশন বলা হয় না

একটি সাধারণ চেক sys.modulesউপযুক্ত ক্রিয়া প্রার্থনা করতে ব্যবহার করা যেতে পারে। স্ক্রিপ্টের নামটিকে স্ট্রিং ( 'test1') হিসাবে উল্লেখ করতে , ' আমদানি ()' বিল্টিন ব্যবহার করুন।

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

3
reloadপাইথন 3 এ গেছে
পাইওটর ডব্রোগোস্ট

1
একটি মডিউল আমদানি করা এটি চালানোর সমতুল্য নয়, if __name__ == "__main__":গার্ড বিবেচনা করুন । আরও কিছু সূক্ষ্ম পার্থক্য থাকতে পারে। বিশ্ব স্তরে স্বেচ্ছাসেবক কোড ছেড়ে যাবেন না। এটিকে একটি ফাংশনে রাখুন এবং পরিবর্তে গৃহীত উত্তরের পরামর্শ অনুযায়ী আমদানির পরে এটিকে কল করুন
jfs

5

আমি রানপি পছন্দ করি :

#!/usr/bin/env python
# coding: utf-8

import runpy

runpy.run_path(path_name='script-01.py')
runpy.run_path(path_name='script-02.py')
runpy.run_path(path_name='script-03.py')

3

কেন শুধু টেস্ট 1 আমদানি করবেন না? প্রতিটি অজগর লিপি একটি মডিউল। আরও ভাল উপায় হ'ল একটি ফাংশন যেমন টেস্ট 1.py এ মূল / চালানো, টেস্ট 1 আমদানি করা এবং টেস্ট 1.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' শর্তের ভিতরে 'প্রস্তাব.py' নামে একটি স্ক্রিপ্ট কার্যকর করতে চান, তবে ব্যবহার করুন,

if condition:
       import recommend

কৌশলটি আলাদা, তবে কাজ করে!

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.