سؤال

في بيثون ، ماذا يفعل بالضبط import * يستورد؟ هل يستورد __init__.py وجدت في المجلد المحتوي؟

على سبيل المثال ، هل من الضروري الإعلان from project.model import __init__, ، أو from project.model import * كافٍ؟

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

المحلول

"ميزة" من from xyz import * على عكس أشكال الاستيراد الأخرى هي أنها تستورد كل شىء (حسنًا ، تقريبًا ... [انظر (أ) أدناه] كل شيء) من الوحدة النمطية المحددة تحت الوحدة الحالية. هذا يسمح باستخدام الكائنات المختلفة (المتغيرات والفئات والأساليب ...) من الوحدة النمطية المستوردة بدون بادئة اسم الوحدة النمطية. علي سبيل المثال

>>> from math import *
>>>pi
3.141592653589793
>>>sin(pi/2)
>>>1.0

ومع ذلك ، فإن هذه الممارسة (لاستيراد * إلى مساحة الاسم الحالية) لا تشجعها لأنه

  • يوفر الفرصة لتصادمات مساحة الاسم (على سبيل المثال ، إذا كان لديك اسم متغير PI قبل الاستيراد)
  • قد يكون غير فعال ، إذا كان عدد الكائنات المستوردة كبيرة
  • لا توثق صراحة أصل المتغير/الطريقة/الفئة (من الجيد أن يكون لديك "الوثائق الذاتية" للبرنامج للزيارة المستقبلية في الكود)

عادةً ما نحد من ممارسة الاستيراد * على الاختبارات المخصصة وما شابه. كما أشار @denilson-sá-maia ، فإن بعض المكتبات مثل (مثل pygame) لها وحدة فرعية حيث يتم تعريف جميع الثوابت والوظائف الأكثر استخدامًا وتكون هذه الوحدات الفرعية بشكل فعال مصمم ليتم استيرادها مع import *. بخلاف هذه الوحدات الفرعية الخاصة ، من الأفضل على خلاف ذلك ...:

استيراد بعض الكائنات بشكل صريح فقط

>>>from math import pi
>>>pi
>>>3.141592653589793
>>> sin(pi/2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sin' is not defined

أو استيراد الوحدة النمطية تحت مساحة الاسم الخاصة بها (أو الاسم المستعار ، لا سيما إذا كان هذا اسمًا طويلًا ، ويشير البرنامج إلى كائناته عدة مرات)

  >>>import math
  >>>math.pi
  >>>3.141592653589793
  etc..


  >>>import math as m  #bad example math being so short and standard...
  >>>m.pi
  >>>3.141592653589793
  etc..

انظر وثائق بيثون حول هذا الموضوع

(أ) على وجه التحديد ، ما يتم استيراده from xyz import * ?
إذا حددت وحدة XYZ __all__ متغير ، سوف يستورد جميع الأسماء المحددة في هذا التسلسل ، وإلا فإنه سوف يستورد جميع الأسماء ، باستثناء تلك التي تبدأ مع السطحي.

ملحوظة العديد من المكتبات لديها الزخارف الفرعية. على سبيل المثال المكتبة القياسية urllib يشمل الزخارف الفرعية مثل urllib.request, urllib.errors, urllib.response وما إلى ذلك نقطة مشتركة للارتباك هي ذلك

from urllib import *

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

نصائح أخرى

إنها تستورد (إلى مساحة الاسم الحالية) أيا كانت تسمية الوحدة النمطية (أو الحزمة) فيها __all__ السمة - في عداد المفقودين مثل هذه السمة ، جميع الأسماء التي لا تبدأ _.

يهدف في الغالب إلى اختصار مفيد للاستخدام فقط في جلسات مترجم تفاعلي: كما تشير الإجابات الأخرى ، لا استخدمه في برنامج.

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

يستورد حزمة (أو أي شيء من الداخل) جوادًا وتنفيذ الحزمة __init__.py - هذا الملف يحدد جسم الحزمة. ومع ذلك ، فإنه لا يربط الاسم __init__ في مساحة الاسم الحالية (لذلك بهذا المعنى ، لا يستورد هذا الاسم).

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

هذا يكفي ، ولكن عمومًا يجب أن تفعل import project.model, الذي يستورد بالفعل __init__.py, ، لكل "فهم واردات بيثون"، ولكن يمكن أن تحصل على كلمة كبيرة إذا كنت تستخدمها أكثر من اللازم ، أو import project.model as pm أو import project.model as model لحفظ بعض ضربات المفاتيح في وقت لاحق عند استخدامه.

اتبع نصيحة أليكس في "ما هو بالضبط الاستيراد "استيراد *"؟"

لو project.model هي حزمة ، والوحدة المشار إليها بواسطة import project.model انه من .../project/model/__init__.py. from project.model import * تفريغ كل شيء من __init__.pyمساحة الاسم في لك. لا يفعل أي شيء تلقائيًا مع الوحدات النمطية الأخرى في النموذج. النمط المفضل __init__.py لا تحتوي على أي شيء.

لم تستخدم أبدًا من أي وقت مضى import *. يجعل الكود الخاص بك غير قابل للقراءة ولا يمكن صيانته.

إذا كانت الوحدة المعنية (project.model في قضيتك) حددت قائمة من اللدائن المسمى __all__, ، ثم يتم استيراد كل متغير اسمه في تلك القائمة. إذا لم يكن هناك مثل هذا المتغير ، فإنه يستورد كل شيء.

فيما يلي طريقة لطيفة لمعرفة ما الذي تم استيراد Star / Asterisk ( *) من وحدة نمطية:

before = dir()
from math import *
after = dir()
print(set(after) - set(before))

عائدات:

{'modf', 'pow', 'erfc', 'copysign', 'sqrt', 'atan2', 'e', 'tanh', 'pi', 'factorial', 'cosh', 'expm1', 'cos', 'fmod', 'frexp', 'log', 'acosh', 'sinh', 'floor', 'isclose', 'lgamma', 'ceil', 'gcd', 'ldexp', 'hypot', 'radians', 'atan', 'isnan', 'atanh', 'before', 'isinf', 'fabs', 'isfinite', 'log10', 'nan', 'tau', 'acos', 'gamma', 'asin', 'log2', 'tan', 'degrees', 'asinh', 'erf', 'fsum', 'inf', 'exp', 'sin', 'trunc', 'log1p'}

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

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