python - كيفية تصحيح في Django ، الطريق الصحيح؟




debugging (23)

لذلك ، بدأت في تعلم Python في Python ولاحقًا Django . في المرات الأولى كان من الصعب النظر في tracebacks وفعلا معرفة ما فعلته خطأ وحيث كان خطأ في بناء الجملة. لقد مر بعض الوقت الآن وبطريقة ما ، أعتقد أني حصلت على روتين في تصحيح رمز دجانجو الخاص بي. بما أن هذا تم في وقت مبكر من تجربة الترميز الخاصة بي ، جلست وتساءلت إذا كان كيف كنت أفعل ذلك غير فعال ويمكن القيام به بشكل أسرع. عادةً ما أتمكن من العثور على الأخطاء وتصحيحها في شفرتي ، لكنني أتساءل عما إذا كان ينبغي عليّ القيام بذلك بشكل أسرع؟

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

لكن هل يمكن تحسين ذلك؟ هل هناك بعض الأدوات الجيدة أو طرق أفضل لتصحيح رمز Django الخاص بك؟


Answers

أسهل طريقة لتصحيح python - خاصة للمبرمجين المستخدمة في Visual Studio - يستخدم PTVS (أدوات Python لـ Visual Studio). الخطوات بسيطة:

  1. قم بتنزيله وتثبيته من http://pytools.codeplex.com/
  2. تعيين breakpoints واضغط F5.
  3. يتم الوصول إلى نقطة الإيقاف الخاصة بك ، يمكنك عرض / تغيير المتغيرات بسهولة مثل تصحيح برامج C # / C ++.
  4. هذا كل شئ :)

إذا كنت تريد تصحيح أخطاء Django باستخدام PTVS ، فستحتاج إلى إجراء ما يلي:

  1. في إعدادات المشروع - علامة التبويب عام ، اضبط "ملف بدء التشغيل" على "manage.py" ، نقطة الدخول لبرنامج Django.
  2. في إعدادات Project - Debug tab ، اضبط "Script Arguments" على "runningerver --noreload". النقطة الأساسية هي "--noreload" هنا. إذا لم تقم بتعيينه ، فلن يتم ضرب نقاط التوقف الخاصة بك.
  3. استمتع بها.

يمكنني استخدام PyCharm (نفس محرك PyCharm ). حقا يساعدني على أن تكون بصريا قادرة على المرور من خلال رمز بلدي ونرى ما يحدث.


أداة سريعة لعلامات القالب:

@register.filter 
def pdb(element):
    import pdb; pdb.set_trace()
    return element

الآن ، داخل أحد القوالب ، يمكنك إجراء {{ template_var|pdb }} وإدخال جلسة pdb (إذا كنت تستخدم خادم التطوير المحلي) حيث يمكنك فحص element إلى محتوى قلبك.

إنها طريقة لطيفة للغاية لمعرفة ما حدث لكائنك عند وصوله إلى القالب.


أثناء التطوير ، إضافة سريع

assert False, value

يمكن أن يساعد في تشخيص المشاكل في طرق العرض أو في أي مكان آخر ، دون الحاجة إلى استخدام مصحح الأخطاء.


أستخدم PyCharm وأدوات تصحيح الأخطاء المختلفة. أيضا لديها مجموعة من المواد لطيفة حول إعداد سهل لتلك الأشياء للمبتدئين. يمكنك البدء من هنا. ويحكي عن PDB و GUI التصحيح بشكل عام مع مشاريع Django. آمل أن يستفيد شخص منهم.


اقتراح إضافي.

يمكنك الاستفادة من nosetests و pdb معا ، بدلا عن طريق حقن pdb.set_trace() في وجهات النظر الخاصة بك يدويا. وتتمثل الميزة في أنه يمكنك مراقبة حالات الخطأ عند بدء التشغيل لأول مرة ، ومن المحتمل أن يكون ذلك في رمز جهة خارجية.

إليك خطأ بالنسبة لي اليوم.

TypeError at /db/hcm91dmo/catalog/records/

render_option() argument after * must be a sequence, not int

....


Error during template rendering

In template /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/crispy_forms/templates/bootstrap3/field.html, error at line 28
render_option() argument after * must be a sequence, not int
18  
19          {% if field|is_checkboxselectmultiple %}
20              {% include 'bootstrap3/layout/checkboxselectmultiple.html' %}
21          {% endif %}
22  
23          {% if field|is_radioselect %}
24              {% include 'bootstrap3/layout/radioselect.html' %}
25          {% endif %}
26  
27          {% if not field|is_checkboxselectmultiple and not field|is_radioselect %}
28  

      {% if field|is_checkbox and form_show_labels %}

الآن ، أعرف أن هذا يعني أنني أخطأت المنشئ للحصول على النموذج ، ولدي فكرة جيدة عن أي حقل يمثل مشكلة. ولكن ، هل يمكنني استخدام pdb لنرى ما هي النماذج المقرمشة التي تشكو منها ، في قالب ؟

أجل، أستطيع. باستخدام خيار --pdb على nosetests:

tests$ nosetests test_urls_catalog.py --pdb

بمجرد أن تصل إلى أي استثناء (بما في ذلك تلك التي يتم التعامل معها بأمان) ، يتوقف pdb حيث يحدث ويمكنني أن ننظر حولها.

  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/forms.py", line 537, in __str__
    return self.as_widget()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/forms.py", line 593, in as_widget
    return force_text(widget.render(name, self.value(), attrs=attrs))
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py", line 513, in render
    options = self.render_options(choices, [value])
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py", line 543, in render_options
    output.append(self.render_option(selected_choices, *option))
TypeError: render_option() argument after * must be a sequence, not int
INFO lib.capture_middleware log write_to_index(http://localhost:8082/db/hcm91dmo/catalog/records.html)
INFO lib.capture_middleware log write_to_index:end
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py(543)render_options()
-> output.append(self.render_option(selected_choices, *option))
(Pdb) import pprint
(Pdb) pprint.PrettyPrinter(indent=4).pprint(self)
<django.forms.widgets.Select object at 0x115fe7d10>
(Pdb) pprint.PrettyPrinter(indent=4).pprint(vars(self))
{   'attrs': {   'class': 'select form-control'},
    'choices': [[('_', 'any type'), (7, (7, 'type 7', 'RECTYPE_TABLE'))]],
    'is_required': False}
(Pdb)         

الآن ، من الواضح أن حجة اختياراتي لمنشئ الحقل المتموج كانت كما لو كانت قائمة ضمن قائمة ، بدلاً من قائمة / مجموعة tuples.

 'choices': [[('_', 'any type'), (7, (7, 'type 7', 'RECTYPE_TABLE'))]]

الشيء الجيد هو أن هذا pdb يحدث داخل رمز كريسبي ، وليس لي وأنا لم أكن في حاجة لإدخاله يدويا.


هناك مجموعة من الطرق للقيام بذلك ، ولكن الأكثر مباشرة هو ببساطة استخدام مصحح الأخطاء Python . ما عليك سوى إضافة السطر التالي إلى وظيفة عرض Django:

import pdb; pdb.set_trace()

إذا حاولت تحميل هذه الصفحة في المستعرض الخاص بك ، فإن المتصفح سوف يتعطل والحصول على مطالبة لمواصلة تصحيح الأخطاء على كود التنفيذ الفعلي.

ومع ذلك هناك خيارات أخرى (أنا لا أوصي بها):

* return HttpResponse({variable to inspect})

* print {variable to inspect}

* raise Exception({variable to inspect})

ولكن يوصى بشدة باستخدام Python Debugger (pdb) لجميع أنواع شفرة Python. إذا كنت بالفعل في pdb ، فستحتاج أيضًا إلى إلقاء نظرة على IPDB الذي يستخدم ipython لتصحيح الأخطاء.

بعض التمديد أكثر فائدة ل pdb هي

pdb++ ، اقترحه Antash .

pudb ، اقترحه PatDuJour .

باستخدام مصحح Python في Django ، اقترح بواسطة Seafangs .


من وجهة نظري ، يمكننا تحليل مهام تصحيح الشفرات الشائعة إلى ثلاثة أنماط استخدام مميزة:

  1. وقد أثار شيء استثناء : django-extensions "Werkzeug المصحح للانقاذ. القدرة على تشغيل التعليمات البرمجية المخصصة في جميع مستويات التتبع هو القاتل. وإذا كنت عالقًا تمامًا ، يمكنك إنشاء Gist للمشاركة بنقرة واحدة فقط.
  2. يتم تقديم الصفحة ، ولكن النتيجة خاطئة : مرة أخرى ، الصخور Werkzeug. لجعل نقطة توقف في التعليمات البرمجية ، فقط اكتب assert False في المكان الذي تريد التوقف عنده.
  3. يعمل الرمز بشكل خاطئ ، لكن المظهر السريع لا يساعد. على الأرجح ، مشكلة حسابية. تنهد. ثم أنا عادة النار حتى مصحح وحدة التحكم pudb : import pudb; pudb.set_trace() import pudb; pudb.set_trace() . الميزة الرئيسية على [i] pdb هو أن PuDB (أثناء النظر كما كنت في الثمانينات) يجعل تعيين تعبيرات الساعة المخصصة نسيم. وتصحيح مجموعة من الحلقات المتداخلة يكون أبسط بكثير باستخدام واجهة المستخدم الرسومية.

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

هكذا يذهب.


معظم الخيارات المذكورة هي alredy. لطباعة سياق القالب ، قمت بإنشاء مكتبة بسيطة لذلك. راجع https://github.com/edoburu/django-debugtools

يمكنك استخدامه لطباعة سياق القالب بدون أي بناء {% load %} :

{% print var %}   prints variable
{% print %}       prints all

ويستخدم تنسيق pprint مخصص لعرض المتغيرات في علامة <pre> .



قم بإضافة import pdb; pdb.set_trace() import pdb; pdb.set_trace() على السطر المقابل في رمز Python وتنفيذها. سيتوقف التنفيذ مع غلاف تفاعلي. في shell ، يمكنك تنفيذ شفرة Python (أي متغيرات الطباعة) أو استخدام أوامر مثل:

  • c متابعة التنفيذ
  • n الخطوة إلى السطر التالي داخل نفس الوظيفة
  • s خطوة إلى السطر التالي في هذه الوظيفة أو وظيفة تسمى
  • q بإنهاء المصحح / التنفيذ

انظر أيضًا: https://poweruser.blog/setting-a-breakpoint-in-python-438e23fe6b28


أنا أوصي epdb (الموسعة Python الموسعة).

https://bitbucket.org/dugan/epdb

شيء واحد أحب حول epdb لتصحيح الأخطاء Django أو webservers Python الأخرى هو الأمر epdb.serve (). يعيّن هذا التتبع ويخدم هذا على منفذ محلي يمكنك الاتصال به. حالة استخدام نموذجي:

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

import epdb; epdb.serve()

بمجرد أن يتم تنفيذ هذا الرمز ، أقوم بفتح مترجم Python وقم بالاتصال بمثيل العرض. يمكنني تحليل جميع القيم والخطوة خلال الشفرة باستخدام أوامر pdb القياسية مثل n و s وما إلى ذلك.

In [2]: import epdb; epdb.connect()
(Epdb) request
<WSGIRequest
path:/foo,
GET:<QueryDict: {}>, 
POST:<QuestDict: {}>,
...
>
(Epdb) request.session.session_key
'i31kq7lljj3up5v7hbw9cff0rga2vlq5'
(Epdb) list
 85         raise some_error.CustomError()
 86 
 87     # Example login view
 88     def login(request, username, password):
 89         import epdb; epdb.serve()
 90  ->     return my_login_method(username, password)
 91
 92     # Example view to show session key
 93     def get_session_key(request):
 94         return request.session.session_key
 95

وأكثر من ذلك يمكنك معرفة المزيد عن مساعدة epdb في أي وقت.

إذا كنت ترغب في عرض أو توصيل عدة مثيلات epdb في نفس الوقت ، فيمكنك تحديد المنفذ للاستماع إليه (الإعداد الافتراضي هو 8080). أي

import epdb; epdb.serve(4242)

>> import epdb; epdb.connect(host='192.168.3.2', port=4242)

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

كملاحظة سريعة ، لا يزال بإمكانك القيام بنفس الشيء مثل الإجابة المقبولة مع epdb ( import epdb; epdb.set_trace() ) ، لكني أردت إبراز وظيفة العرض لأنني وجدتها مفيدة جدًا.


أجد Visual Studio Code رائع لتصحيح أخطاء تطبيقات Django. تعمل معلمات launchyjon القياسية python على تشغيل python manage.py مع مصحح الأخطاء المرفقة ، بحيث يمكنك ضبط نقاط التوقف والدخول خلال الشفرة كما تشاء.


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

لا بد لي من القول ، أن PyCharm يأخذ الكثير من الذاكرة. لكن مرة أخرى ، لا شيء جيد في الحياة. لقد أتيت للتو بأحدث إصدار 3. كما أنها تلعب بشكل جيد للغاية مع Django و Flask و Google AppEngine. لذا ، على العموم ، أود أن أقول إنها أداة رائعة ومفيدة لأي مطور.

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


لقد دفعت django-pdb إلى django-pdb . إنه تطبيق بسيط يعني أنك لست بحاجة إلى تعديل شفرة المصدر في كل مرة تريد فيها اختراق pdb.

التثبيت هو فقط ...

  1. pip install django-pdb
  2. أضف 'django_pdb' إلى INSTALLED_APPS

يمكنك الآن التشغيل: manage.py runserver --pdb لاقتحام pdb في بداية كل مشاهدة ...

bash: manage.py runserver --pdb
Validating models...

0 errors found
Django version 1.3, using settings 'testproject.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

GET /
function "myview" in testapp/views.py:6
args: ()
kwargs: {}

> /Users/tom/github/django-pdb/testproject/testapp/views.py(7)myview()
-> a = 1
(Pdb)

وتشغيل: manage.py test --pdb لاقتحام pdb على فشل الإختبارات / أخطاء ...

bash: manage.py test testapp --pdb
Creating test database for alias 'default'...
E
======================================================================
>>> test_error (testapp.tests.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ".../django-pdb/testproject/testapp/tests.py", line 16, in test_error
    one_plus_one = four
NameError: global name 'four' is not defined
======================================================================

> /Users/tom/github/django-pdb/testproject/testapp/tests.py(16)test_error()
-> one_plus_one = four
(Pdb)

يستضيف المشروع على GitHub ، المساهمات موضع ترحيب بالطبع.



أنا حقاً أحب المصحح التفاعلي لـ Werkzeug . تشبه صفحة debug في Django ، إلا أنه يمكنك الحصول على غلاف تفاعلي على كل مستوى من التتبع. إذا كنت تستخدم django-extensions ، فستحصل على أمر إدارة runserver_plus يبدأ خادم التطوير ويمنحك مصحح الأخطاء الخاص بـ Werkzeug على الاستثناءات.

بالطبع ، يجب عليك فقط تشغيل هذا محليًا ، لأنه يمنح أي شخص لديه متصفح الحق في تنفيذ شفرة python عشوائية في سياق الخادم.


استخدم pdb أو ipdb . Diffrence بين هذين هما ipdb يدعم السيارات كاملة.

ل pdb

import pdb
pdb.set_trace()

ل ipdb

import ipdb
ipdb.set_trace()

لتنفيذ مفتاح السطر الجديد ، اضغط على مفتاح c للمتابعة. تحقق من المزيد من الخيارات باستخدام help(pdb)


كما هو مذكور في مشاركات أخرى هنا - تحديد نقاط التوقف في التعليمات البرمجية الخاصة بك والمشي من خلال التعليمات البرمجية لمعرفة ما إذا كان يتصرف كما هو متوقع هو طريقة رائعة لتعلم شيء مثل Django حتى يكون لديك فكرة جيدة عن سلوك كل ذلك - وما رمزك هو فعل.

للقيام بذلك ، أوصي باستخدام WingIde. تماما مثل غيرها من IDEs لطيفة وسهلة الاستخدام ، تخطيط لطيف وأيضا من السهل أن تحدد breakpoints / تعديل المكدس الخ. مثالي لتصور ما تقوم به الكود الخاص بك أثناء الخطو خلاله. أنا من أشد المعجبين به.

أنا أيضا استخدام PyCharm - لديها تحليل رمز ثابت ممتازة ويمكن أن تساعد في بعض الأحيان اكتشاف المشاكل قبل أن تدرك أنهم هناك.

كما ذكر بالفعل django-debug-toolbar ضروري - https://github.com/django-debug-toolbar/django-debug-toolbar

وعلى الرغم من عدم صراحة أداة تصحيح أو تحليل - واحدة من المفضلة هي SQL Middleware المتاحة من Django Snippets على https://djangosnippets.org/snippets/290/

سيقوم هذا بعرض استعلامات SQL التي أنشأها العرض الخاص بك. سيعطيك ذلك إحساسًا جيدًا لما تقوم به ORM وإذا كانت استعلاماتك فعالة أو تحتاج إلى إعادة صياغة التعليمات البرمجية (أو إضافة التخزين المؤقت).

أجد أنه لا يقدر بثمن لابقاء العين على أداء الاستعلام أثناء تطوير وتصحيح طلبي.

نصيحة واحدة فقط - لقد قمت بتعديله قليلاً لاستخدامي الخاص لإظهار الملخص فقط وليس عبارة SQL .... لذلك أنا استخدمه دائمًا أثناء التطوير والاختبار. أضفت أيضًا أنه إذا كان len (connection.queries) أكبر من عتبة محددة مسبقًا ، فإنه يعرض تحذيرًا إضافيًا.

ثم إذا كنت أرى شيئا سيئا (من أداء أو عدد من منظور الاستعلامات) يحدث أنا أعود مرة أخرى على العرض الكامل للعبارات SQL لنرى بالضبط ما يجري. سهل جداً عندما تعمل على مشروع كبير في Django مع العديد من المطورين.


هناك بعض الأدوات التي تتعاون بشكل جيد ويمكن أن تجعل مهمة تصحيح الأخطاء أسهل.

الأهم من ذلك هو شريط أدوات تصحيح Django .

ثم تحتاج إلى تسجيل جيد باستخدام مرفق logging بايثون. يمكنك إرسال إخراج التسجيل إلى ملف سجل ، ولكن خيارًا أسهل هو إرسال إخراج السجل إلى firepython . لاستخدام هذا تحتاج إلى استخدام متصفح فايرفوكس مع ملحق firebug . يتضمن Firepython مكونًا إضافيًا لمكافحة الحرائق يعرض أي تسجيل من جانب الخادم في علامة التبويب Firebug.

يعد Firebug نفسه مهمًا أيضًا لتصحيح أخطاء جافا سكريبت في أي تطبيق تقوم بتطويره. (على افتراض أن لديك بعض JS رمز بالطبع).

أنا أيضا أحب django-viewtools لتصحيح الأخطاء بشكل تفاعلي باستخدام pdb ، لكني لا django-viewtools كثيرا.

هناك المزيد من الأدوات المفيدة مثل الجرافة لتتبع تسرب الذاكرة (هناك أيضًا اقتراحات جيدة أخرى تم تقديمها في الإجابات هنا على SO لتتبع الذاكرة).


بالنسبة لأولئك الذين يمكنهم إضافة pdb عن طريق الخطأ إلى عمليات مباشرة ، يمكنني اقتراح هذا الامتداد لإجابة #Koobz:

@register.filter 
def pdb(element):
    from django.conf import settings
    if settings.DEBUG:    
        import pdb
        pdb.set_trace()
    return element

في بعض الأحيان عندما أتمكن من استكشاف طريقة معينة واستدعاء pdb أمر مرهق للغاية ، أود أن أضيف:

import IPython; IPython.embed()

يبدأ IPython.embed() shell IPython التي لديها الوصول إلى المتغيرات المحلية من النقطة حيث يمكنك الاتصال به.


هناك أيضًا SL4A مكتوبة بشكل كبير بواسطة موظفي Google.





python django debugging