estributeError: "الوحدة النمطية" لا يوجد لديه سمة

StackOverflow https://stackoverflow.com/questions/1250103

  •  12-09-2019
  •  | 
  •  

سؤال

لدي نوعان من وحدات بيثون:

صباحا

import b

def hello():
  print "hello"

print "a.py"
print hello()
print b.hi()

B.py.

import a

def hi():
  print "hi"

عندما أركض a.py, ، انا حصلت:

AttributeError: 'module' object has no attribute 'hi'

ماذا يعني الخطأ؟ كيف أصلحه؟

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

المحلول

لديك واردات متبادلة المستوى الأعلى، والتي هي دائما فكرة سيئة تقريبا.

إذا كان يجب أن يكون لديك حقا واردات متبادلة في بيثون، فإن طريقة القيام بذلك هي استيرادها ضمن دالة:

# In b.py:
def cause_a_to_do_something():
    import a
    a.do_something()

الآن يمكن أن تفعل A.PY بأمان import b دون التسبب في مشاكل.

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

نصائح أخرى

لقد رأيت أيضا هذا الخطأ عند تسمية وحدة نمطية عن غير قصد بنفس الاسم كأحد وحدات Python القياسية. على سبيل المثال كان لدي وحدة تسمى commands وهي أيضا وحدة مكتبة بيثون. ثبت أن هذا أمر صعب التتبع لأنه يعمل بشكل صحيح على بيئة التطوير المحلية ولكنه فشل في الخطأ المحدد عند تشغيل محرك تطبيق Google.

المشكلة هي الاعتماد الدائري بين الوحدات النمطية. a الواردات b و b الواردات a. وبعد ولكن يحتاج أحدهم إلى تحميل أولا - في هذه الحالة، ينتهي بيثون وحدة تهيئة الوحدة a قبل b و b.hi() غير موجود حتى الآن عند محاولة الوصول إليها a.

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

from package import MyEnumClass
# ...
# in some method:
return MyEnumClass.Member

الاستيراد الصحيح:

from package.MyEnumClass import MyEnumClass

نأمل أن يساعد شخص ما

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

import a.b, a.c

# ...

something(a.b)
something(a.c)
something(a.d)  # My addition, which failed.

السطر الأخير أدى إلى AttributeError. وبعد كان السبب أنني قد فشلت في ملاحظة أن نقل الأسفل a (a.b و a.c) كانت صراحة المستوردة، وفترض أن import بيان مستورد فعلا a.

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

ركضت في هذه المشكلة عندما راجعت نسخة أقدم من مستودع من GIT. استبدال git بلدي .py الملفات، ولكن تركت غير مقصودة .pyc الملفات. منذ .py الملفات و .pyc كانت الملفات خارج المزامنة، import القيادة في أ .py تعذر العثور على الملف الوحدة المقابلة في .pyc الملفات.

كان الحل ببساطة لحذف .pyc الملفات، واسمحوا لهم أن يتم تجديدها تلقائيا.

واجهت نفس القضية. ثابت باستخدام reload.

import the_module_name
from importlib import reload
reload(the_module_name)

لست متأكدا كيف ولكن التغيير أدناه فرز مشكلتي:

كنت أحصل على اسم الملف واستيراد الاسم نفسه على سبيل المثال، كان لدي اسم ملف emoji.py وكنت أحاول استيراد emoji. ولكن تغيير اسم الملف حل المشكلة.

نأمل ذلك يساعد

تسبب واردات دائرية تسبب مشاكل، لكن بايثون لديه طرق لتخفيفها مدمج.

المشكلة هي عند تشغيل python a.py, ، يعمل a.py ولكن ليس علامة استيرادها كوحدة. لذلك بدوره a.py -> وحدة الواردات B -> وحدة الواردات A -> وحدة الواردات B. آخر الاستيراد غير المرجع منذ باء يجري حاليا المستوردة وحراس ثعبان ضد ذلك. و ب هي وحدة فارغة الآن. لذلك عندما ينفذ b.hi(), ، لا يمكن العثور على أي شيء.

نلاحظ أن b.hi() التي تم تنفيذها أثناء a.py -> الوحدة النمطية ب -> الوحدة، ليس في a.py مباشرة.

في مثالك الخاص، يمكنك تشغيل فقط python -c 'import a' في المستوى الأعلى، لذلك التنفيذ الأول لل a.py هو مسجل لاستيراد وحدة نمطية.

@ MD5 نفسه بالنسبة لي، حاول تغيير اسم الوحدة النمطية أو استيراد وظيفة مباشرة

على أوبونتو 18.04. ( virtualenv., python.3.6.x.)، ما يلي إعادة تحميل مقتطف تم حلها المشكلة بالنسبة لي:

Main.py.

import my_module  # my_modyle.py
from importlib import reload # reload 
reload(my_module)

print(my_module)
print(my_modeule.hello())

أين:

|--main.py    
|--my_module.py

للمزيد من توثيق التحقق من : هنا

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