سؤال

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

المشكلة

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

## File 1
def f1():  print "go f1!"

class C1(object):
    def do_eval(self,x):  # maybe this should be do_evil, given what happens
        print "evaling"
        eval(x)
        eval(x,globals(),locals())

ثم قم بتشغيل هذا الرمز من جلسة تفاعلية، وسيكون هناك الكثير منها NameErrors

## interactive
class C2(object):
    def do_eval(self,x):  # maybe this should be do_evil, given what happens
        print "evaling"
        eval(x)
        eval(x,globals(),locals())

def f2():
    print "go f2!"

from file1 import C1
import file1

C1().do_eval('file1.f1()')
C1().do_eval('f1()')
C1().do_eval('f2()')

file1.C1().do_eval('file1.f1()')
file1.C1().do_eval('f1()')
file1.C1().do_eval('f2()')

C2().do_eval('f2()')
C2().do_eval('file1.f1()')
C2().do_eval('f1()')

هل هناك لغة/نمط مشترك لهذا النوع من المهام؟هل أنبح الشجرة الخطأ تمامًا؟

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

المحلول

في هذا المثال، يمكنك ببساطة تسليم الوظائف ككائنات إلى الأساليب الموجودة C1:

>>> class C1(object):
>>>    def eval(self, x):
>>>        x()
>>>
>>> def f2(): print "go f2"
>>> c = C1()
>>> c.eval(f2)
go f2

في Python، يمكنك تمرير الوظائف والفئات إلى طرق أخرى واستدعائها/إنشائها هناك.

إذا كنت تريد تقييم سلسلة تعليمات برمجية فعليًا، فيجب عليك تحديد البيئة، كما ذكر توماس بالفعل.

الوحدة الخاصة بك من الأعلى، تغيرت قليلاً:

## File 1
def f1():  print "go f1!"

class C1(object):
    def do_eval(self, x, e_globals = globals(), e_locals = locals()):
        eval(x, e_globals, e_locals)

والآن في المترجم التفاعلي:

>>> def f2():
>>>    print "go f2!"
>>> from file1 import *    # 1
>>> C1().do_eval("f2()")   # 2
NameError: name 'f2' is not defined

>>> C1().do_eval("f2()", globals(), locals()) #3
go f2!
>>> C1().do_eval("f1()", globals(), locals()) #4
go f1!

بعض الشروح

  1. هنا، نقوم بإدراج كافة الكائنات من file1 في مساحة الاسم لهذه الوحدة
  2. f2 ليس في مساحة الاسم file1, ، وبالتالي نحصل على NameError
  3. الآن نقوم بتمرير البيئة بشكل صريح، ويمكن تقييم الكود
  4. f1 موجود في مساحة اسم هذه الوحدة، لأننا قمنا باستيراده

يحرر:تمت إضافة نموذج التعليمات البرمجية حول كيفية تمرير البيئة بشكل صريح eval.

نصائح أخرى

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

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

قد ترغب في إلقاء نظرة على فئة string.Template، التي تحاول القيام بشيء مماثل.

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