পাইথনে, আমি কি আমদানি করা মডিউলটির মূল () কল করতে পারি?


87

পাইথনে আমার একটি মডিউল myModule.py রয়েছে যেখানে আমি কয়েকটি ফাংশন এবং একটি প্রধান () সংজ্ঞায়িত করি , যা কয়েকটি কমান্ড লাইন আর্গুমেন্ট গ্রহণ করে।

আমি সাধারণত এটিকে প্রধান () বাশ স্ক্রিপ্ট থেকে কল করি। এখন, আমি সবকিছুকে একটি ছোট প্যাকেজের মধ্যে রাখতে চাই , তাই আমি ভেবেছিলাম যে আমি আমার সাধারণ বাশ স্ক্রিপ্টটিকে একটি পাইথন স্ক্রিপ্টে পরিণত করতে এবং প্যাকেজে রেখে দিতে পারি।

সুতরাং, আমি আসলে কি মেন () কল myModule.py ফাংশন প্রধান () ফাংশান থেকে MyFormerBashScript.py এর? আমি কি এটা করতে পারি? আমি এটিতে কোনও যুক্তি কীভাবে দেব ?


আপনি যদি মাইমডুল আমদানি করে থাকেন তবে আপনার কল করা উচিত myModule.main()। এ পর্যন্ত কি কি চেষ্টা করেছ?
মারিয়াস

আমি ইনপুট আর্গুমেন্টগুলি দ্বারা উদ্বিগ্ন, যা আমি সাধারণত শেল স্ক্রিপ্ট থেকে পাস করি।
রিকি রবিনসন

subprocessমডিউলটির সাথে এটি কল করার কোনও অর্থ নেই ?
বেনডুন্ডি

আমার ধারণা এটি সহজ হবে, হ্যাঁ
রিকি রবিনসন

উত্তর:


116

এটি কেবল একটি ফাংশন। এটি আমদানি করুন এবং কল করুন:

import myModule

myModule.main()

আপনার যদি যুক্তিগুলি বিশ্লেষণের প্রয়োজন হয় তবে আপনার কাছে দুটি বিকল্প রয়েছে:

  • এগুলিকে পার্স করুন main(), তবে sys.argvপ্যারামিটার হিসাবে প্রবেশ করুন (একই মডিউলে সমস্ত কোড নীচে myModule):

    def main(args):
        # parse arguments using optparse or argparse or what have you
    
    if __name__ == '__main__':
        import sys
        main(sys.argv[1:])
    

    এখন আপনি myModule.main(['arg1', 'arg2', 'arg3'])অন্য অন্য মডিউল থেকে আমদানি এবং কল করতে পারেন ।

  • আছে main()প্যারামিটার ইতিমধ্যে (আবার সমস্ত কোড পার্স করা হয় গ্রহণ myModuleমডিউল):

    def main(foo, bar, baz='spam'):
        # run with already parsed arguments
    
    if __name__ == '__main__':
        import sys
        # parse sys.argv[1:] using optparse or argparse or what have you
        main(foovalue, barvalue, **dictofoptions)
    

    এবং আমদানি করুন এবং myModule.main(foovalue, barvalue, baz='ham')অন্য কোথাও কল করুন এবং অজগর আর্গুমেন্টগুলি প্রয়োজনীয় হিসাবে পাস করুন।

এখানে কৌশলটি হ'ল কখন আপনার মডিউলটি স্ক্রিপ্ট হিসাবে ব্যবহৃত হচ্ছে; আপনি যখন মূল স্ক্রিপ্ট হিসাবে পাইথন ফাইলটি চালান ( python filename.py) কোনও importবিবৃতি ব্যবহৃত হচ্ছে না, তাই পাইথন সেই মডিউলটিকে কল করে "__main__"। তবে যদি সেই একই কোডটিকে filename.pyমডিউল ( import filename) হিসাবে বিবেচনা করা হয় , তবে পাইথন সেইটিকে পরিবর্তে মডিউল নাম হিসাবে ব্যবহার করে। উভয় ক্ষেত্রে চলক __name__সেট করা আছে, এবং এর বিপরীতে পরীক্ষা করা আপনাকে জানায় যে আপনার কোডটি কীভাবে চালানো হয়েছিল।


4
অবশ্যই কিন্তু ইনপুট আর্গুমেন্ট সম্পর্কে কি? আমি ব্যবহার করি argparse, তাই যখন আমি টার্মিনাল থেকে স্ক্রিপ্ট কল করি তখনই করি $ python myModule -a input_a -b input_b --parameterC input_c। পাইথন কোডের মধ্যে থেকে এটি কীভাবে কাজ করবে? এটিই আমি সাধারণ অনুসন্ধান থেকে খুঁজে পাইনি।
রিকি রবিনসন

@ রিকি রবিনসন: এটি উভয় উপায়ে রাখতে পারবেন তা দেখানোর জন্য প্রসারিত; বিশ্লেষণ বা পার্সড হওয়া যুক্তিগুলি কেবল পাস করুন।
মার্টিজন পিটারস

4
ধন্যবাদ আপনি কি দয়া করে কোডটির কোন অংশটি কোন মডিউল বা স্ক্রিপ্টের সাথে সম্পর্কিত তা নির্দিষ্ট করতে পারেন? শুরুতে আমি যা ভেবেছিলাম তার চেয়ে এটিকে আরও জটিল মনে হচ্ছে।
রিকি রবিনসন

@ রিকিরোবিনসন: উভয় অংশই একই মডিউলে অন্তর্ভুক্ত; আমি তা স্পষ্ট করে দিয়েছি
মার্টিজন পিটারস

42

মার্তিজেনের উত্তরটি বোধগম্য হয়, তবে এটি এমন কিছু গুরুত্বপূর্ণ বিষয় হারিয়েছিল যা অন্যের কাছে সুস্পষ্ট বলে মনে হতে পারে তবে আমার পক্ষে তা নির্ধারণ করা শক্ত ছিল।

আপনি যে সংস্করণটি আরগপার্স ব্যবহার করেন সেখানে আপনার মূল শৃঙ্খলে এই লাইন থাকা দরকার।

args = parser.parse_args(args)

সাধারণত যখন আপনি কেবল একটি স্ক্রিপ্টে আরগপার্স ব্যবহার করছেন তখন আপনি কেবল লিখুন

args = parser.parse_args()

এবং parse_args কমান্ড লাইন থেকে যুক্তিগুলি সন্ধান করে। তবে এক্ষেত্রে মূল ফাংশনে কমান্ড লাইন আর্গুমেন্টের অ্যাক্সেস নেই, সুতরাং আপনাকে আরগপার্স বলতে হবে আর্গুমেন্টগুলি কী।

এখানে একটি উদাহরণ

import argparse
import sys

def x(x_center, y_center):
    print "X center:", x_center
    print "Y center:", y_center

def main(args):
    parser = argparse.ArgumentParser(description="Do something.")
    parser.add_argument("-x", "--xcenter", type=float, default= 2, required=False)
    parser.add_argument("-y", "--ycenter", type=float, default= 4, required=False)
    args = parser.parse_args(args)
    x(args.xcenter, args.ycenter)

if __name__ == '__main__':
    main(sys.argv[1:])

ধরে নিলে আপনি এই মাইস্টেস্ট.পিটির নাম দিয়েছেন এটি চালানোর জন্য আপনি কমান্ড লাইন থেকে এগুলির যে কোনও একটি করতে পারেন

python ./mytest.py -x 8
python ./mytest.py -x 8 -y 2
python ./mytest.py 

যা যথাক্রমে ফিরে আসে

X center: 8.0
Y center: 4

বা

X center: 8.0
Y center: 2.0

বা

X center: 2
Y center: 4

অথবা আপনি যদি অন্য একটি অজগর স্ক্রিপ্ট থেকে চালাতে চান তবে আপনি এটি করতে পারেন

import mytest
mytest.main(["-x","7","-y","6"]) 

যা ফিরে আসে

X center: 7.0
Y center: 6.0

4
এটি ঠিক আমার যা প্রয়োজন ছিল - সহায়ক সংযোজনের জন্য আপনাকে অনেক ধন্যবাদ
এইচএফব্রাউনিং

এটি পাইথন 2 এর সাথে কাজ করে থাকতে পারে তবে পাইথন 3 এ এটি আর কাজ করে না, মডিউলটির মূল () ফাংশনটি কল করতে পারে না:AttributeError: module 'sqlacodegen' has no attribute 'main'
NaturalBornCamper

26

এটা নির্ভর করে. যদি মূল কোডটি একটি ifহিসাবে সুরক্ষিত থাকে :

if __name__ == '__main__':
    ...main code...

তাহলে না, আপনি পাইথনকে এটি কার্যকর করতে পারবেন না কারণ আপনি স্বয়ংক্রিয় পরিবর্তনশীলকে প্রভাবিত করতে পারবেন না __name__

কিন্তু যখন সমস্ত কোড কোনও ফাংশনে থাকে, তখন তা সক্ষম হতে পারে। চেষ্টা করুন

import myModule

myModule.main()

এটি মডিউলটি যখন নিজেকে দিয়ে সুরক্ষিত করে তখনও কাজ করে __all__

from myModule import *mainআপনার কাছে দৃশ্যমান নাও হতে পারে , তাই আপনাকে মডিউলটি নিজেই আমদানি করতে হবে।


ওহ ঠিক আছে, স্পষ্টতার জন্য ধন্যবাদ। আমি সবকিছু একটি প্রধান () ফাংশনে রেখেছি, তাই এটি ঠিক হওয়া উচিত। এই "দ্বিতীয়" প্রধানটিতে ইনপুট আর্গুমেন্টগুলি কীভাবে পাস করতে হবে সে সম্পর্কে আমি আরও উদ্বিগ্ন। এটি করার কোনও সহজ উপায়?
রিকি রবিনসন

অবশ্যই:import sys; module.main(sys.argv);
হারুন ডিগুল্লা

এটি অ্যাক্সেস সম্পর্কে একটি দুর্দান্ত বিকল্প ব্যাখ্যা __main__যা আমাকে সাহায্য করেছিল, ধন্যবাদ @ অ্যারোন ডিজিগুল্লা
চার্লি জি

এখানে একটি কৌতুক অন্য ফাংশন থেকে একটি প্রধান কল হয় stackoverflow.com/a/20158605/3244382
PatriceG

3

আমারও একই ব্যবহারের প্রয়োজন ছিল argparse। জিনিসটি parse_argsকোনও argparse.ArgumentParserঅবজেক্টের উদাহরণস্বরূপ কাজ থেকে স্পষ্টতই তার তর্কগুলি ডিফল্টরূপে গ্রহণ করে sys.args। মার্টিজন লাইনকে অনুসরণ করে চারপাশের কাজগুলি সেই স্পষ্ট করে তোলে, যাতে আপনি আর্গুমেন্টগুলিকে parse_argsইচ্ছা হিসাবে পাস করতে পারেন ।

def main(args):
    # some stuff
    parser = argparse.ArgumentParser()
    # some other stuff
    parsed_args = parser.parse_args(args)
    # more stuff with the args

if __name__ == '__main__':
    import sys
    main(sys.argv[1:])

মূল পয়েন্টটি parse_argsকার্য করতে আরোগুলি পার করছে । পরে, প্রধানটি ব্যবহার করতে আপনি মার্তিজান যেমন বলে তেমনই করেন।


3

আমি যে উত্তরটির সন্ধান করছিলাম সেটির উত্তর এখানে দেওয়া হয়েছিল: sys.argv ব্যতীত আরগগুলি দিয়ে পাইথন আরগপারস কীভাবে ব্যবহার করবেন?

যদি main.pyএবং parse_args()এভাবে লেখা হয় তবে পার্সিংটি দুর্দান্তভাবে করা যায়

# main.py
import argparse
def parse_args():
    parser = argparse.ArgumentParser(description="")
    parser.add_argument('--input', default='my_input.txt')
    return parser

def main(args):
    print(args.input)

if __name__ == "__main__":
    parser = parse_args()
    args = parser.parse_args()
    main(args)

তারপরে আপনি এটি দিয়ে অন্য অজগর স্ক্রিপ্টে এর main()সাথে যুক্তিগুলি কল এবং পার্স করতে পারেন parser.parse_args(['--input', 'foobar.txt']):

# temp.py
from main import main, parse_args
parser = parse_args()
args = parser.parse_args([]) # note the square bracket
# to overwrite default, use parser.parse_args(['--input', 'foobar.txt'])
print(args) # Namespace(input='my_input.txt')
main(args)

0

ধরে নিচ্ছি আপনি কমান্ড লাইন আর্গুমেন্টগুলিও পাশ করার চেষ্টা করছেন।

import sys
import myModule


def main():
    # this will just pass all of the system arguments as is
    myModule.main(*sys.argv)

    # all the argv but the script name
    myModule.main(*sys.argv[1:])

ধন্যবাদ আমি আসলে argparseপরিবর্তে ব্যবহার করছি sys.argv। এই ক্ষেত্রে এটি কীভাবে পরিবর্তিত হবে? এছাড়াও, বাইরের স্ক্রিপ্ট থেকে আমি কেবলমাত্র কিছু ইনপুট আর্গুমেন্ট ব্যবহারকারীদের টাইপ করতে চাই, যখন অভ্যন্তরীণ স্ক্রিপ্টের জন্য অন্যান্য ইনপুট আর্গুমেন্টগুলি (মাইমডিউল.পি) আমার দ্বারা হার্ডকড করে।
রিকি রবিনসন

কোডটি নিজেই না দেখে সুনির্দিষ্ট উত্তর দেওয়া শক্ত। সাধারণভাবে, আপনি কেবল যে কোনও যুক্তিই পাস করবেন। *Unpacks একটি অ্যারের f(a) => f([1,2,3])বনাম f(*a) => f(1,2,3) আপনি শুধু সহজে কাজ করতে পারে myModule.main(sys.argv[1], "other value", 39)বা যাই হোক না কেন।
আগেবেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.