سؤال

يبدو أنهم ألغوا في Python 3 بكل سهولة لتحميل البرنامج النصي بسرعة عن طريق الإزالة execfile()

هل هناك بديل واضح أفتقده؟

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

المحلول

وفقا للوثائق, ، بدلاً من

execfile("./filename") 

يستخدم

exec(open("./filename").read())

يرى:

نصائح أخرى

من المفترض فقط أن تقرأ الملف وتنفذ الكود بنفسك.2to3 يستبدل الحالي

execfile("somefile.py", global_vars, local_vars)

مثل

with open("somefile.py") as f:
    code = compile(f.read(), "somefile.py", 'exec')
    exec(code, global_vars, local_vars)

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

يرى:

بينما exec(open("filename").read()) غالبا ما يعطى كبديل ل execfile("filename"), ، فإنه يفتقد التفاصيل الهامة التي execfile أيد.

الوظيفة التالية لـ Python3.x هي أقرب ما يمكن أن أحصل عليه من نفس السلوك مثل تنفيذ الملف مباشرة.هذا يتوافق مع الجري python /path/to/somefile.py.

def execfile(filepath, globals=None, locals=None):
    if globals is None:
        globals = {}
    globals.update({
        "__file__": filepath,
        "__name__": "__main__",
    })
    with open(filepath, 'rb') as file:
        exec(compile(file.read(), filepath, 'exec'), globals, locals)

# execute the file
execfile("/path/to/somefile.py")

ملحوظات:

  • يستخدم القراءة الثنائية لتجنب مشاكل الترميز
  • ضمان إغلاق الملف (Python3.x يحذر من هذا)
  • يعرف __main__, ، تعتمد بعض البرامج النصية على هذا للتحقق مما إذا كان يتم تحميلها كوحدة نمطية أم لا، على سبيل المثال. if __name__ == "__main__"
  • جلسة __file__ هو أجمل لرسائل الاستثناء واستخدام بعض البرامج النصية __file__ للحصول على مسارات الملفات الأخرى المتعلقة بها.
  • يأخذ وسيطات globals & locals اختيارية، ويعدلها في مكانها كـ execfile يفعل - حتى تتمكن من الوصول إلى أي متغيرات محددة عن طريق قراءة المتغيرات مرة أخرى بعد التشغيل.

  • على عكس Python2 execfile هذا لا لا تعديل مساحة الاسم الحالية بشكل افتراضي.لذلك عليك أن تمر صراحة globals() & locals().

مثل مقترح على بيثون ديف القائمة البريدية مؤخرًا, runpy قد تكون الوحدة بديلاً قابلاً للتطبيق.نقلا عن تلك الرسالة:

https://docs.python.org/3/library/runpy.html#runpy.run_path

import runpy
file_globals = runpy.run_path("file.py")

هناك اختلافات طفيفة ل execfile:

  • run_path يقوم دائمًا بإنشاء مساحة اسم جديدة.إنه ينفذ التعليمات البرمجية كوحدة نمطية، لذلك لا يوجد فرق بين العالمية والمحلية (ولهذا السبب لا يوجد سوى init_globals دعوى).يتم إرجاع العوالم.

    execfile يتم تنفيذها في مساحة الاسم الحالية أو مساحة الاسم المحددة.دلالات locals و globals, ، إذا تم تقديمها، كانت مشابهة للسكان المحليين والعالميين داخل تعريف الفئة.

  • run_path لا يمكنه تنفيذ الملفات فحسب، بل يمكنه أيضًا تنفيذ البيض والأدلة (راجع وثائقه للحصول على التفاصيل).

وهذا واحد هو أفضل، لأنه يأخذ غلوبالس والسكان المحليين من المتصل:

import sys
def execfile(filename, globals=None, locals=None):
    if globals is None:
        globals = sys._getframe(1).f_globals
    if locals is None:
        locals = sys._getframe(1).f_locals
    with open(filename, "r") as fh:
        exec(fh.read()+"\n", globals, locals)

هل يمكن كتابة الدالة الخاصة:

def xfile(afile, globalz=None, localz=None):
    with open(afile, "r") as fh:
        exec(fh.read(), globalz, localz)

إذا كنت في حاجة حقا إلى ...

وإذا كان البرنامج النصي الذي تريد تحميل في نفس الدليل من واحد تشغيل، ربما "استيراد" سوف قيام بهذه المهمة؟

إذا كنت بحاجة إلى استيراد كود حيوي وظيفة المدمج في __ __ استيراد وحدة عفريت تستحق النظر.

>>> import sys
>>> sys.path = ['/path/to/script'] + sys.path
>>> __import__('test')
<module 'test' from '/path/to/script/test.pyc'>
>>> __import__('test').run()
'Hello world!'

وtest.py:

def run():
        return "Hello world!"

إذا كنت تستخدم بايثون 3.1 أو في وقت لاحق، يجب عليك أيضا أن تأخذ نظرة على الموقع importlib .

وإليك ما كان (يتم تعيين file بالفعل إلى المسار إلى الملف مع شفرة المصدر في كل من الأمثلة):

execfile(file)

وهنا ما استبداله:

exec(compile(open(file).read(), file, 'exec'))

والجزء المفضل: الإصدار الثاني يعمل على ما يرام في كل من 2 و 3 بيثون، وهذا يعني أنه ليس من الضروري إضافة في الإصدار منطق يعتمد

.

لاحظ أن نمط أعلاه ستفشل إذا كنت تستخدم الإعلانات ترميز PEP-263 التي لا أسكي أو UTF-8. كنت بحاجة إلى العثور على ترميز البيانات، وصياغته صحيح قبل تسليمه إلى إكسيك ().

class python3Execfile(object):
    def _get_file_encoding(self, filename):
        with open(filename, 'rb') as fp:
            try:
                return tokenize.detect_encoding(fp.readline)[0]
            except SyntaxError:
                return "utf-8"

    def my_execfile(filename):
        globals['__file__'] = filename
        with open(filename, 'r', encoding=self._get_file_encoding(filename)) as fp:
            contents = fp.read()
        if not contents.endswith("\n"):
            # http://bugs.python.org/issue10204
            contents += "\n"
        exec(contents, globals, globals)

وأيضا، في حين ليس حلا بيثون النقي، إذا كنت تستخدم IPython (وربما كنت ينبغي على أي حال)، يمكنك القيام به:

%run /path/to/filename.py

والتي من السهل على حد سواء.

وأنا مجرد مبتدئ هنا حتى ربما هو الحظ نقية إذا وجدت هذا:

وبعد محاولة تشغيل برنامج نصي من المترجم موجه >>> مع الأمر

    execfile('filename.py')

والتي حصلت على "NameError: اسم 'execfile" لم يتم تعريف "حاولت أساسية جدا

    import filename

وانها عملت بشكل جيد: -)

وآمل أن يكون هذا يمكن أن تكون مفيدة، وأشكركم جميعا على تلميحات كبيرة، والأمثلة وجميع تلك القطع علق المتقن من التعليمات البرمجية التي هي مصدر إلهام كبير للقادمين الجدد!

ويمكنني استخدام أوبونتو 16،014 LTS إلى x64. بايثون 3.5.2 (افتراضيا، 17 نوفمبر 2016، 17:05:23) [GCC 5.4.0 20160609] على لينكس

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