سؤال

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

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

في بيثون الموازي ، سأرسل حالات متعددة من "Mainfunc" إلى وظيفة "إرسال" من PP. يجب أن يكون كل منهما قادرًا على الوصول إلى "keyseq". سيكون من الرائع أن يصلوا جميعًا إلى نفس مثيل KeySeq حتى لا يكون لدى أي من العقد على الأشجار التي تم إرجاعها نفس المفتاح ، لكن يمكنني الالتفاف على ذلك إذا لزم الأمر.

لذلك: سؤالي يدور حول حشو كل شيء في Mainfunc. شكرًا (تحرير) إذا لم أقم بتضمين كل شيء في MainFunc ، فيجب أن أحاول إخبار PP بالوظائف التابعة ، وما إلى ذلك عن طريق تمرير مختلف الحجج في أماكن مختلفة. أحاول تجنب ذلك.

(تحرير متأخر) إذا تم استدعاء ks.next () داخل وظيفة "cender () ، فإنه يعيد الخطأ" nameerror: الاسم العالمي "KS" غير محدد "

class KeySeq:
    "Iterator to produce sequential \
    integers for keys in dict"
    def __init__(self, data = 0):
        self.data = data
    def __iter__(self):
        return self
    def next(self):
        self.data = self.data + 1
        return self.data
class One:
    'some code'
class Two:
    'some code'
class Three:
    'some code'
class Utilities:
    def generate(x):
        '___________'
    def obfiscate(y):
        '___________'
    def ruminate(z):
        '__________'


def mainfunc(z):
    ks = KeySeq()
    one = One()
    two = Two()
    three = Three()
    utilities = Utilities()
    list_of_interest = utilities.generate(5)
    return list_of_interest

result = mainfunc(params)
هل كانت مفيدة؟

المحلول

إذا كنت تريد كل حالات mainfunc لاستخدام نفس الشيء KeySeq كائن ، يمكنك استخدام خدعة قيمة المعلمة الافتراضية:

def mainfunc(ks=KeySeq()):
   key = ks.next()

طالما أنك لا تمر بالفعل في قيمة ks, ، جميع الدعوات إلى mainfunc سوف تستخدم مثيل KeySeq تم إنشاؤه عندما تم تعريف الوظيفة.

إليك السبب ، في حال كنت لا تعرف: الوظيفة هي كائن. لديها سمات. تم تسمية إحدى سماته func_defaults; ؛ إنه tuple تحتوي على القيم الافتراضية لجميع الوسائط في توقيعها التي لها افتراضات. عندما تتصل بوظيفة ولا تقدم قيمة للوسيطة التي لها افتراضي ، فإن الوظيفة تسترد القيمة من func_defaults. لذلك عندما تتصل mainfunc دون توفير قيمة ل ks, ، يحصل على KeySeq() مثال على func_defaults Tuple. الذي ، لتلك الحالة من mainfunc, ، هو نفسه دائما KeySeq نموذج.

الآن ، تقول أنك سترسل "مثيلات متعددة mainfunc إلى submit وظيفة pp. "هل تعني حقًا مثيلات متعددة؟ إذا كان الأمر كذلك ، فإن الآلية التي أصفها لن تعمل.

ولكن من الصعب إنشاء مثيلات متعددة من وظيفة (والرمز الذي نشرته لا). على سبيل المثال ، تقوم هذه الوظيفة بإرجاع مثيل جديد من g في كل مرة يطلق عليها:

>>> def f():
        def g(x=[]):
            return x
        return g
>>> g1 = f()
>>> g2 = f()
>>> g1().append('a')
>>> g2().append('b')
>>> g1()
['a']
>>> g2()
['b']

إذا اتصلت g() مع عدم وجود وسيطة ، فإنه يعيد القيمة الافتراضية (في البداية قائمة فارغة) من func_defaults Tuple. حيث g1 و g2 هي حالات مختلفة من g وظيفة ، القيمة الافتراضية ل x الحجة ايضا مثيل مختلف ، والذي يوضح أعلاه.

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

def mainfunc (): إذا لم يكن hasattr (mainfunc ، "ks"): setattr (mainfunc ، "ks" ، keyseq () key = mainfunc.ks.next ()

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

نصائح أخرى

من الجيد هيكل برنامجك بهذه الطريقة. تتبع الكثير من أدوات سطر الأوامر نفس النمط:

#imports, utilities, other functions

def main(arg):
    #...

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

بهذه الطريقة يمكنك الاتصال main وظيفة من وحدة أخرى عن طريق استيرادها ، أو يمكنك تشغيلها من سطر الأوامر.

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

أساسيات بيثون - الفصول

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