كيفية التقاط مخرجات مترجم Python و/أو CMD.EXE من برنامج Python النصي؟

StackOverflow https://stackoverflow.com/questions/24931

  •  09-06-2019
  •  | 
  •  

سؤال

  1. هل من الممكن التقاط مخرجات مترجم بايثون من برنامج بايثون النصي؟
  2. هل من الممكن التقاط مخرجات Windows CMD من برنامج Python النصي؟

إذا كان الأمر كذلك، ما هو librar(y|ies) الذي يجب أن أبحث فيه؟

هل كانت مفيدة؟

المحلول

إذا كنت تتحدث عن مترجم python أو CMD.exe الذي يعد "الأصل" للبرنامج النصي الخاص بك، فلا، فهذا غير ممكن.في كل نظام يشبه POSIX (يبدو أنك تستخدم الآن Windows، وقد يكون لذلك بعض المراوغات التي لا أعرف عنها، YMMV) تحتوي كل عملية على ثلاثة تدفقات، الإدخال القياسي، والإخراج القياسي، والخطأ القياسي.Bu بشكل افتراضي (عند التشغيل في وحدة التحكم) يتم توجيهها إلى وحدة التحكم، ولكن إعادة التوجيه ممكنة باستخدام تدوين توجيه الإخراج:

python script_a.py | python script_b.py

يؤدي هذا إلى ربط دفق الإخراج القياسي للبرنامج النصي أ بتدفق الإدخال القياسي للبرنامج النصي ب.لا يزال الخطأ القياسي ينتقل إلى وحدة التحكم في هذا المثال.انظر المقال على تيارات القياسية على ويكيبيديا.

إذا كنت تتحدث عن عملية فرعية، فيمكنك تشغيلها من لغة python هكذا (يعد stdin أيضًا خيارًا إذا كنت تريد الاتصال ثنائي الاتجاه):

import subprocess
# Of course you can open things other than python here :)
process = subprocess.Popen(["python", "main.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
x = process.stderr.readline()
y = process.stdout.readline()
process.wait()

شاهد بايثون عملية فرعية وحدة للحصول على معلومات حول إدارة العملية.للاتصالات، تعتبر أنابيبprocess.stdin وprocess.stdout قياسية كائنات الملف.

للاستخدام مع الأنابيب، القراءة من المدخلات القياسية كما lassevk اقترح عليك أن تفعل شيئا مثل هذا:

import sys
x = sys.stderr.readline()
y = sys.stdin.readline()

sys.stdin وsys.stdout عبارة عن كائنات ملفات قياسية كما هو مذكور أعلاه، والمحددة في ملف sys وحدة.قد ترغب أيضًا في إلقاء نظرة على أنابيب وحدة.

قراءة البيانات باستخدام readline() كما في المثال الخاص بي هي طريقة ساذجة جدًا للحصول على البيانات.إذا لم يكن الإخراج موجهًا نحو الخط أو غير محدد، فربما تريد النظر فيه الاقتراع والذي للأسف لا يعمل في نظام التشغيل Windows، ولكنني متأكد من وجود بعض البدائل هناك.

نصائح أخرى

أعتقد أنه يمكنني توجيهك إلى إجابة جيدة للجزء الأول من سؤالك.

1.هل من الممكن التقاط إخراج مترجم بيثون من نص بيثون؟

الجواب هو "نعم"، وشخصيًا أحب ما يلي مرفوعًا من الأمثلة الموجودة في بيب 343--بيان "مع". وثيقة.

from contextlib import contextmanager
import sys

@contextmanager
def stdout_redirected(new_stdout):
    saved_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout.close()
        sys.stdout = saved_stdout

وتستخدم مثل هذا:

with stdout_redirected(open("filename.txt", "w")):
    print "Hello world"

أحد الجوانب الرائعة فيه هو أنه يمكن تطبيقه بشكل انتقائي حول جزء فقط من تنفيذ البرنامج النصي، بدلاً من نطاقه بالكامل، ويظل ساري المفعول حتى عند ظهور الاستثناءات غير المعالجة في سياقه.إذا قمت بإعادة فتح الملف في وضع الإلحاق بعد استخدامه لأول مرة، فيمكنك تجميع النتائج في ملف واحد:

with stdout_redirected(open("filename.txt", "w")):
    print "Hello world"

print "screen only output again"

with stdout_redirected(open("filename.txt", "a")):
    print "Hello world2"

وبطبيعة الحال، يمكن أيضًا توسيع ما سبق ليشمل إعادة التوجيه أيضًا sys.stderr إلى نفس الملف أو إلى ملف آخر.انظر هذا أيضا إجابة إلى سؤال ذي صلة.

في الواقع، يمكنك ذلك بالتأكيد، وهي جميلة وقبيحة ومجنونة في نفس الوقت!

يمكنك استبدال sys.stdout وsys.stderr بكائنات StringIO التي تجمع المخرجات.

إليك مثال، احفظه باسم evil.py:

import sys
import StringIO

s = StringIO.StringIO()

sys.stdout = s

print "hey, this isn't going to stdout at all!"
print "where is it ?"

sys.stderr.write('It actually went to a StringIO object, I will show you now:\n')
sys.stderr.write(s.getvalue())

عند تشغيل هذا البرنامج سوف تجد ما يلي:

  • لم يذهب أي شيء إلى stdout (حيث تتم طباعة الطباعة عادةً)
  • السلسلة الأولى التي تتم كتابتها إلى stderr هي تلك التي تبدأ بـ "It"
  • السطران التاليان هما الخطان اللذان تم جمعهما في كائن StringIO

استبدال sys.stdout/err بهذا الشكل هو تطبيق لما يسمى Monkeypatching.قد تختلف الآراء حول ما إذا كان هذا "مدعمًا" أم لا، وهو بالتأكيد اختراق قبيح، لكنه أنقذ لحم الخنزير المقدد عند محاولة الالتفاف حول أشياء خارجية مرة أو مرتين.

تم اختباره على Linux، وليس على Windows، ولكن يجب أن يعمل أيضًا.اسمحوا لي أن أعرف إذا كان يعمل على نظام التشغيل Windows!

انت تريد عملية فرعية.انظر على وجه التحديد إلى Popen في 17.1.1 وتواصل في 17.1.2.

في أي سياق تسأل؟

هل تحاول التقاط الإخراج من برنامج تبدأه في سطر الأوامر؟

إذا كان الأمر كذلك، فهذه هي كيفية تنفيذها:

somescript.py | your-capture-program-here

ولقراءة الإخراج، ما عليك سوى القراءة من الإدخال القياسي.

من ناحية أخرى، إذا كنت تقوم بتنفيذ هذا البرنامج النصي أو cmd.exe أو ما شابه ذلك من داخل برنامجك، وتريد الانتظار حتى انتهاء البرنامج النصي/البرنامج، والتقاط جميع مخرجاته، فأنت بحاجة إلى إلقاء نظرة على المكتبة المكالمات التي تستخدمها لبدء هذا البرنامج الخارجي، فمن المرجح أن هناك طريقة لمطالبته بإعطائك طريقة ما لقراءة الإخراج وانتظار الانتهاء.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top