يجب استخدام العمومي للوصول إلى المتغير المحلي (ليس لدي أي فكرة عن السبب) بيثون؛كيفي
سؤال
لقد قمت مؤخرًا بتنزيل Kivy لأنه قدم لي البرامج التعليمية والوثائق الأكثر قابلية للفهم، وما إلى ذلك.لقد جربت pygame وcocos لكن لم أتمكن مطلقًا من الحصول على كريم أساس، ومع Kivy كان الأمر سهلاً.
إذن هذه هي مشكلتي، لقد صنعت لعبة بونج، وأحاول إيقاف اللعبة مؤقتًا عن طريق إيقاف كرة البونج، ثم تشغيلها مرة أخرى عندما لا تكون متوقفة مؤقتًا (عن طريق تغيير سرعتها).
هذا هو الكود الخاص بي:
class PongGame(Widget):
...
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
if keycode[1] == 'escape':
#Why doesnt it work without global?
#If I don't use a global i get "tempBallVelocity referenced before assignment
global tempBallVelocity
tempBallVelocity = self.ball.velocity
self.ball.velocity = 0,0
if keycode[1] == '`':
#Make the ball go again, thus exiting pause
#This is where the error occurs if I don't use global
self.ball.velocity = tempBallVelocity
كما ترون في التعليقات، إذا لم أستخدم العمومي، فسيتم الرجوع إلي قبل حدوث خطأ في المهمة.ولكنه متغير محلي، وأنا لا أفهم لماذا يحدث هذا.
هل لدي احد اى افكار؟شكرًا؟
يحرر:فقط للتأكد من أن الجميع واضحون في نواياي، لا أريد استخدام العالمية، ولكنها الطريقة الوحيدة التي ستنجح.أفضّل عدم استخدام الكرة العالمية.
المحلول
إذا أصلحت خطأ المسافة البادئة مرة أخرى، فسترى ما يلي:يمكنك مشاهدة هذا:
الهروب
escape
يجب أن تعمل دون العالمية، ولكنtempBallVelocity
سيتم اعتباره متغيرا محليا.إذا كنت تريد تعديل متغير عام، فأنت بحاجة إلى إضافة الإعلان العام لإخبار بايثون بذلكtempBallVelocity
ليست محلية بل عالمية.وفي الحالة الثانية،
tempBallVelocity
لا تتم تهيئته محليًا إذا لم تقم بإدخال كتلة الهروب وبالتالي لا يمكن استخدامه كمحلي قيمة R.في هذه الحالة، يجب على بايثون البحث عن المتغير خارج الفصل.يكونtempBallVelocity
حقا متغير عالمي؟
ملاحظة:إذا كانت الحالات حصرية فيجب عليك استخدامها elif
بدلاً من if
للحالة الثانية.
نصائح أخرى
لم يتم وضع مسافة بادئة للكود الموجود داخل الوظيفة، فهل هذا مجرد خطأ في النسخ؟إذا لم يكن الأمر كذلك، فأنا أتساءل لماذا لا تحصل على خطأ.
يحرر:حسنًا، من السهل أن تقوم بتعيين المتغير tempBallVelocity
عند استدعاء الوظيفة مع 'escape'
ولكن بعد ذلك تخرج الوظيفة وتفقد المتغير.إذا اتصلت به بعد ذلك بـ "backtick"، فأنت لم تقم بتعيين المتغير tempBallVelocity
ومع ذلك، ربما يكون الحل الأفضل هو:self.tempBallVelocity = self.ball.velocity
.
في كل مرة تقوم فيها بتعيين متغير داخل كتلة معرفية من التعليمات البرمجية، يتم تدمير المتغير بمجرد الخروج من هذه الكتلة، مرة أخرى إلى العنوان السابق؛
إذا كتبت
giveacodicetagpre.داخل برنامج نصي ضخم، يتعامل Python فقط متغير FOO فقط أثناء وجوده "في الداخل"، وبمجرد أن ينتهي الأمر ويخرج، يتم نسيت Foo بالكامل من أجل جعل الأمور أسرع، من المفهوم أنه إذا قمت بتعيين متغير داخل عبارة، ستستخدمها فقط داخل هذا البيان.
إذا كنت تريد أن تفعل شيئا مثل هذا
giveacodicetagpre.يجب عليك تعيين متغير FOO خارج البيانات "إذا" البيانات
giveacodicetagpre.أو يمكنك أيضا القيام بذلك عن طريق إعداد Foo كمغير عالمي، لذلك لا يتم تدميره بمجرد الوصول إلى عبارة "IF"
giveacodicetagpre.ولكن قد يكون ذلك غير طبيعي ومربكة في معظم الدوافع، أو حتى مشكلة إذا بدأت في جعل كل شيء عالمي متغيرات تستخدمه فقط مرة واحدة تتراكم بعطل على ذاكرة جهازك أثناء البرنامج.
الآن تكتب فئة، لذلك فإن الطريقة الصحيحة للقيام بما تفعله سيكون (من وجهة نظري) لتخزين متغير "tempballocity" في فئة مثل هذا
giveacodicetagpre.يبدو أنه لا يحترم القاعدة التي أخبرتك بها للتو إلا أن الشيء هنا هو أنه عند كتابة "Self.tempballVallocity= ..." تقوم بتخزين المعلومات في الذات، وهو الاختصار ل كائن Ponggame الذي ستقوم بإلقاؤه من أجل تشغيل اللعبة، والتي ستقوم بتشغيل هذه الطريقة، وبالتالي فإن المتغير ينفجر مخزن هناك عند الخروج من الطريقة.
آمل أن تكون هذه الإجابة مفيدة لك، يجب عليك الحصول على معرفة أكثر صلابة حول بيثون، تعلم بيثون الطريق الصعب هو موقع كتاب مع نسخة HTML مجانية كانت مفيدة بالنسبة لي.