الساخنة مبادلة كود بايثون (بطة نوع الوظائف؟)

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

  •  26-09-2019
  •  | 
  •  

سؤال

لقد تم التفكير في هذا طويلة جدا و لم تكن قد حصلت على أي فكرة, ربما كنت يمكن أن تساعد.

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

Top piece of code (always the same)
Middle piece of code (changes from file to file)
Bottom piece of code (always the same)

و أدركت اليوم أن هذا هو فكرة سيئة ، على سبيل المثال ، إذا كنت ترغب في تغيير شيء من أعلى أو أسفل أقسام ، أريد أن أكتب شيل للقيام بذلك.(هذا ليس من الصعب يبدو انها سيئة للغاية رمز الحكمة).

لذا ما أريد أن أفعله هو واحد الخارجي بيثون السيناريو الذي هو من هذا القبيل:

Top piece of code
Dynamic function that calls the middle piece of code (based on a parameter)
Bottom piece of code

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

لذلك فكرت حتى اثنين من أكثر الحلول:

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

    نظام التشغيل.الأمر(sys.argv[0] scriptName.py)

    التي من شأنها أن تشغيل البرنامج النصي ، ولكن يدعو الثعبان إلى استدعاء الثعبان لا تبدو أنيقة جدا بالنسبة لي.

هل لديك أي أفكار أخرى ؟ شكرا لك.

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

المحلول

إذا كنت تعرف اسم الدالة كسلسلة و اسم وحدة من سلسلة ثم يمكنك أن تفعل

mod = __import__(module_name)
fn = getattr(mod, fn_name)
fn()

نصائح أخرى

حل آخر ممكن هو أن يكون كل المتكررة ملفات استيراد وظيفة من الملف الرئيسي

from topAndBottom import top, bottom
top()
# do middle stuff
bottom()

بالإضافة إلى العديد من الإجابات التي نشرت بالفعل ، والنظر في طريقة القالب نمط التصميم:جعل فئة مجردة مثل

class Base(object):
    def top(self): ...
    def bottom(self): ...
    def middle(self): raise NotImplementedError
    def doit(self):
        self.top()
        self.middle()
        self.bottom()

كل للتوصيل وحدة ثم يجعل الطبقة التي يرث من هذا Base ويجب أن تجاوز middle مع رمز ذات الصلة.

ربما لا يبرر هذه الحالة بسيطة (لا يزال لديك لاستيراد وحدة الحق في إنشاء فئتها و الاتصال doit على ذلك), ولكن لا يزال يستحق الأخذ في الاعتبار (جنبا إلى جنب مع العديد من Pythonic الاختلافات التي يجب وبإسهاب في العديد من التكنولوجيا محادثات متاح الآن على موقع يوتيوب) في الحالات التي يكون فيها عدد أو تعقيد "للتوصيل قطع" يستمر في النمو -- طريقة القالب (على الرغم من البشعين اسم;-) الصلبة, مجربة و تدرجية عالية نمط [[أحيانا صبي جامدة جدا ، ولكن هذا هو بالضبط ما أتناول في هذه التكنولوجيا محادثات -- و هذه المشكلة لا تنطبق هذه الحالة استخدام]].

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

سوف تعمل على ما يرام - استخدام __import__ مدمج أو, إذا كان لديك معقدة جدا تخطيط ، عفريت الوحدة النمطية استيراد السيناريو الخاص بك.ثم يمكنك الحصول على وظيفة من قبل module.__dict__[funcname] على سبيل المثال.

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

exec(open(filename).read(None))

ماذا عن هذا ؟

function do_thing_one():
   pass

function do_thing_two():
   pass

dispatch = { "one" : do_thing_one,
             "two" : do_thing_two,
           }

# do something to get your string from the command line (optparse, argv, whatever)
# and put it in variable "mystring"

# do top thing
f = dispatch[mystring]
f()
# do bottom thing
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top