it-swarm.asia

Python 3: UnboundLocalError: المتغير المحلي المشار إليه قبل التعيين

يعطي الرمز التالي الخطأ UnboundLocalError: local variable 'Var1' referenced before assignment:

Var1 = 1
Var2 = 0
def function(): 
    if Var2 == 0 and Var1 > 0:
        print("Result One")
    Elif Var2 == 1 and Var1 > 0:
        print("Result Two")
    Elif Var1 < 1:
        print("Result Three")
    Var1 =- 1
function()

كيف يمكنني اصلاح هذا؟ شكرا على اي مساعدة!

140
Eden Crow

يمكنك إصلاح ذلك عن طريق تمرير المعلمات بدلاً من الاعتماد على Globals

def function(Var1, Var2): 
    if Var2 == 0 and Var1 > 0:
        print("Result One")
    Elif Var2 == 1 and Var1 > 0:
        print("Result Two")
    Elif Var1 < 1:
        print("Result Three")
    return Var1 - 1
function(1, 1)
40
Jakob Bowyer

هذا لأنه على الرغم من وجود Var1 ، إلا أنك تستخدم أيضًا بيان مهمة باسم Var1 داخل الوظيفة (Var1 -= 1 في السطر السفلي). بطبيعة الحال ، يؤدي هذا إلى إنشاء متغير داخل نطاق الوظيفة يسمى Var1 (بصدق ، يقوم -= أو += بتحديث (إعادة تعيين) متغير موجود فقط ، ولكن لأسباب غير معروفة (التناسق المحتمل في هذا السياق) ، يقوم Python بمعاملته كواجب). يرى مترجم Python هذا في وقت تحميل الوحدة النمطية ويقرر (بشكل صحيح) عدم استخدام رمز النطاق العمومي Var1 داخل النطاق المحلي ، مما يؤدي إلى حدوث مشكلة عند محاولة الرجوع إلى المتغير قبل تعيينه محليًا.

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

global Var1, Var2

داخل الجزء العلوي من وظيفتك. سيُعلم هذا Python أنك لا تنوي تحديد Var1 أو Var2 متغير داخل النطاق المحلي للوظيفة. يرى مترجم Python هذا في وقت تحميل الوحدة النمطية ويقرر (بشكل صحيح) البحث عن أي إشارات إلى المتغيرات المذكورة أعلاه في النطاق العالمي.

بعض الموارد

  • يحتوي موقع Python على شرح رائع لهذه المشكلة الشائعة.
  • يقدم Python 3 بيانًا { nonlocal ذا صلة - تحقق من ذلك أيضًا.
322
orokusaki

إذا قمت بتعيين قيمة متغير داخل الوظيفة ، فإن python يفهمها على أنها إنشاء متغير محلي بهذا الاسم. هذا المتغير المحلي يقنع المتغير العام.

في حالتك ، يُنظر إلى Var1 كمتغير محلي ، ويتم استخدامه قبل التعيين ، وبالتالي الخطأ.

لحل هذه المشكلة ، يمكنك أن تقول صراحة أنها عالمية من خلال وضع global Var1 في وظيفتك.

Var1 = 1
Var2 = 0
def function():
    global Var1
    if Var2 == 0 and Var1 > 0:
        print("Result One")
    Elif Var2 == 1 and Var1 > 0:
        print("Result Two")
    Elif Var1 < 1:
        print("Result Three")
    Var1 =- 1
function()
64
madjar

لا أحب هذا السلوك ، لكن هكذا تعمل بيثون. لقد تم إجابة السؤال من قبل الآخرين ، ولكن من أجل الاكتمال ، اسمحوا لي أن أشير إلى أن Python 2 لديها المزيد من هذه المراوغات.

def f(x):
    return x

def main():
    print f(3)
    if (True):
        print [f for f in [1, 2, 3]]

main()

إرجاع Python 2.7.6 خطأ:

Traceback (most recent call last):
  File "weird.py", line 9, in <module>
    main()
  File "weird.py", line 5, in main
    print f(3)
UnboundLocalError: local variable 'f' referenced before assignment

يرى Python أن f يستخدم كمتغير محلي في [f for f in [1, 2, 3]] ، ويقرر أنه أيضًا متغير محلي في f(3). يمكنك إضافة عبارة global f:

def f(x):
    return x

def main():
    global f
    print f(3)
    if (True):
        print [f for f in [1, 2, 3]]

main()

انها تقوم بالعمل؛ ومع ذلك ، يصبح f 3 في النهاية ... وهذا هو ، print [f for f in [1, 2, 3]] الآن يغير المتغير العام f إلى 3 ، لذلك لم تعد وظيفة بعد الآن.

لحسن الحظ ، يعمل بشكل جيد في Python3 بعد إضافة الأقواس إلى print.

9
osa

لماذا لا تقوم ببساطة بإرجاع القيمة المحسوبة والسماح للمتصل بتعديل المتغير العام. ليس من الجيد التعامل مع متغير عمومي داخل دالة ، على النحو التالي:

Var1 = 1
Var2 = 0

def function(): 
    if Var2 == 0 and Var1 > 0:
        print("Result One")
    Elif Var2 == 1 and Var1 > 0:
        print("Result Two")
    Elif Var1 < 1:
        print("Result Three")
    return Var1 - 1

Var1 = function()

أو حتى إنشاء نسخ محلية من المتغيرات العامة والعمل معها وإرجاع النتائج التي يمكن للمتصل تعيينها بشكل مناسب

def function():
v1, v2 = Var1, Var2
# calculate using the local variables v1 & v2
return v1 - 1

Var1 = function()
2
ctx