سؤال

من بين الطرق المختلفة لاستيراد التعليمات البرمجية، هل هناك بعض الطرق الأفضل استخدامها، مقارنة بالآخرين؟ هذا الرابط http://effbot.org/zone/import-confusion.htm. في الولايات قصيرة ذلك

from foo.bar import MyClass

ليست الطريقة المفضلة لاستيراد MyClass في ظل الظروف العادية أو ما لم تعرف ما تفعله. (بدلا من ذلك، طريقة أفضل ترغب:

import foo.bar as foobaralias

ثم في التعليمات البرمجية، للوصول إلى استخدام myclass

foobaralias.MyClass

)

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

ومع ذلك، فإن هذه المادة التي ربطتها قديمة حقا.

لقد سمعت أيضا أنه من الأفضل، على الأقل في سياق مشاريع DJANGO، بدلا من ذلك فقط استيراد الفصول التي تريد استخدامها، بدلا من الوحدة النمطية بأكملها. لقد قيل إن هذا النموذج يساعد على تجنب أخطاء الواردات الدائرية أو على الأقل يجعل نظام استيراد DJango أقل هشاشة. تمت الإشارة إلى أن رمز DJango الخاص يبدو يفضل "من X Import y" أكثر من "استيراد X".

على افتراض أن المشروع الذي أعمل فيه لا يستخدم أي ميزات خاصة لل __init__.py ... (كل منا __init__.py الملفات فارغة)، ما طريقة الاستيراد يجب أن أؤيد، ولماذا؟

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

المحلول

بالنسبة لي، يعتمد على الوضع. إذا كانت طريقة / فئة مسماة بشكل فريد (أي ليس كذلك process() أو شيء من هذا القبيل)، وسوف تستخدمه كثيرا, ، ثم حفظ الكتابة وفك from foo import MyClass.

إذا كنت تقوم باستيراد أشياء متعددة من وحدة نمطية واحدة، فمن الأفضل فقط استيراد الوحدة، والقيام بذلك module.bar, module.foo, module.baz, ، وما إلى ذلك، للحفاظ على مساحة الاسم نظيفة.

قلت أيضا

لقد قيل إن هذا النموذج يساعد على تجنب أخطاء الواردات الدائرية أو على الأقل يجعل نظام استيراد DJango أقل هشاشة. تمت الإشارة إلى أن رمز DJango الخاص يبدو يفضل "من X Import y" أكثر من "استيراد X".

لا أرى كيف سيساعد طريقة إحدى الطرق أو الآخر في منع الواردات الدائرية. السبب هو أنه حتى عندما تفعل from x import y, ، كل x يتم استيرادها. فقط y يتم إحضارها إلى مساحة الاسم الحالية، ولكن الوحدة بأكملها x جاري العمل. جرب هذا المثال:

في Test.py، ضع ما يلي:

def a():
    print "a"

print "hi"

def b():
    print "b"

print "bye"

ثم في "Runme.py"، وضع:

from test import b

b()

ثم فقط تفعل python runme.py

سترى الإخراج التالي:

hi
bye
b

لذلك تم تشغيل كل شيء في الاختبار. على الرغم من أنك مستورد فقط b

نصائح أخرى

أولا، وأولي، قاعدة الواردات: لا تستخدم أبدا from foo import *.

تناقش المقالة مسألة الواردات الدورية، والتي لا تزال موجودة اليوم في قانون ضعيف منظم. أنا لا أحب الواردات الدورية؛ وجودهم هو علامة قوية على أن بعض الوحدة تفعل الكثير، ويجب تقسيمها. إذا لأي سبب من الأسباب، فأنت بحاجة إلى العمل برمز مع الواردات الدورية التي لا يمكن إعادة ترتيبها، import foo هو الخيار الوحيد.

لمعظم الحالات، لا يوجد فرق كبير بين import foo و from foo import MyClass. وبعد أنا أفضل الثانية، لأن هناك أقل من الكتابة المعنية، ولكن هناك عدد قليل من الأسباب التي قد أستخدمها الأولى:

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

    • جيد: import myapp.utils as utils; utils.frobnicate()
    • جيد: import myapp.utils as U; U.frobnicate()
    • سيئ: from myapp.utils import frobnicate
  • أنت تقوم باستيراد الكثير من القيم من وحدة واحدة. احفظ أصابعك وعينك القارئ.

    • سيئ: from myapp.utils import frobnicate, foo, bar, baz, MyClass, SomeOtherClass, # yada yada

ميزة الأخيرة هي أن أصل myclass هو أكثر صراحة. السابق يضع myclass في مساحة الاسم الحالية حتى يمكن للقانون استخدام myclass غير مؤهل. لذلك فهو أقل وضوحا لشخص يقرأ الكود حيث يتم تعريف myclass.

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