ImportError: X नाम आयात नहीं कर सकता


540

मेरे पास नाम की चार अलग-अलग फाइलें हैं: मुख्य, वेक्टर, इकाई और भौतिकी। मैं सभी कोड पोस्ट नहीं करूंगा, सिर्फ आयात, क्योंकि मुझे लगता है कि जहां त्रुटि है। (आप चाहें तो मैं और पोस्ट कर सकते हैं)

मुख्य:

import time
from entity import Ent
from vector import Vect
#the rest just creates an entity and prints the result of movement

निकाय:

from vector import Vect
from physics import Physics
class Ent:
    #holds vector information and id
def tick(self, dt):
    #this is where physics changes the velocity and position vectors

वेक्टर:

from math import *
class Vect:
    #holds i, j, k, and does vector math

भौतिक विज्ञान:

from entity import Ent
class Physics:
    #physics class gets an entity and does physics calculations on it.

मैं तब main.py से चलता हूँ और मुझे निम्न त्रुटि मिलती है:

Traceback (most recent call last):
File "main.py", line 2, in <module>
    from entity import Ent
File ".../entity.py", line 5, in <module>
    from physics import Physics
File ".../physics.py", line 2, in <module>
    from entity import Ent
ImportError: cannot import name Ent

मैं पायथन के लिए बहुत नया हूं लेकिन लंबे समय तक सी ++ के साथ काम किया है। मैं अनुमान लगा रहा हूं कि त्रुटि दो बार इकाई आयात करने के कारण है, एक बार मुख्य रूप से, और बाद में भौतिकी में, लेकिन मुझे कोई हल नहीं पता। क्या कोई मदद कर सकता है?


वे कहाँ और किस निर्देशिका में संग्रहीत हैं, उनकी निर्देशिका संरचना क्या है?
बेन

1
अजगर में लूप-आयात के लिए इस उत्तर पर एक नज़र डालें: stackoverflow.com/questions/7199466/…
ग्रेगर

सामान्य तौर पर, यह करने के लिए अच्छा कोडिंग अभ्यास नहीं है from <module> import <name>, या from <modlue> import *। मॉड्यूल नाम स्थान के तहत आयात करने के लिए बेहतर है कि नामांकित संदर्भों को अधिलेखित करने की संभावना को रोकने के लिए।
जोएल कॉर्नेट

1
@jsells तुम सिर्फ अपनी कक्षाओं बुलाना चाहिए Entityऔर Vectorके बजाय Entऔर Vect, इस तरह के नाम छोटे कर लिए कोई कारण नहीं है। और हाँ, उपयोग करें import vectorऔर फिर x = vector.Vector(0,0,0)

7
हे @ केविन जब से आप जावा को बेहतर जानते हैं, 2008 के इस लेख में आपका क्या प्रभाव है, जहां लेखक का पहला वाक्य जावा में "सुंदर सामान्य अभ्यास" के लिए परिपत्र निर्भरता को दर्शाता है ?
हेवचटइस

जवाबों:


502

आपके पास परिपत्र निर्भर आयात हैं। वर्ग से परिभाषित होने physics.pyसे entityपहले आयात किया Entजाता है और physicsआयात करने की कोशिश करता है entityजो पहले से ही प्रारंभिक है। मॉड्यूल physicsसे निर्भरता निकालें entity


5
अपने कोड को रीफ़ैक्टर करने के लिए आप बहुत कुछ नहीं कर सकते हैं। यदि आप Ent constructor में Physics को संदर्भित नहीं करते हैं, तो Ent के नीचे परिभाषा को मूव करें। यदि आप करते हैं, तो निर्माण के बाद आयात को सक्षम करने के लिए सेटफ़िज़िक्स जैसी विधि जोड़ें।
तेमू इकोनेंन

12
@jsells चूंकि आपने सी ++ के साथ लंबे समय तक काम किया है, इसलिए आपको पता होना चाहिए कि दो वर्गों को एक-दूसरे पर निर्भर होना चाहिए। C ++ में यह अत्यंत महत्वपूर्ण है, और भले ही यह पायथन में # 1 चीज नहीं है, फिर भी इस नियम का पालन करना वास्तव में अच्छा विचार है। कभी दो वर्ग होते हैं जो एक दूसरे को जानते हैं, कभी भी। यदि आपको अपनी कक्षाओं के लिए संरचना बनाने में मदद चाहिए, तो बाकी कोड भी पोस्ट करें। वास्तव में किस प्रकार (कोड के संदर्भ में) कर रहे हैं Entityऔर Physicsएक दूसरे से जुड़ा हुआ? मुझे यकीन है कि आप जो करने की कोशिश कर रहे हैं उसके लिए एक समाधान है।

7
@ user2032433 यह वास्तव में आपके द्वारा 'एक-दूसरे को जानने' के अर्थ पर निर्भर करता है। यह सच है कि अच्छा डिज़ाइन आमतौर पर एक तरफ़ा निर्भरता का एक पेड़ पैदा करता है और यह आम तौर पर सबसे अच्छा तरीका है। लेकिन इसके अपवाद भी हैं। सी ++ कक्षाएं निश्चित रूप से एक दूसरे को परिपत्र रूप से संदर्भित कर सकती हैं। (हालांकि यह उनके लिए एक दूसरे से बना होना असंभव है।) फॉरवर्ड-डिक्लेरेशन के बिना, यह पायथन में एक समस्या है जिसमें हमेशा सी ++ समाधान नहीं होता है।
जॉन मैकफ़ारलेन

93
बयान "दो वर्गों को कभी एक-दूसरे पर निर्भर होना चाहिए" बकवास है। ऑब्जेक्ट ओरिएंटेशन में दो तरह (द्विदिश) नेविगेशन बहुत आम है। books.google.co.uk/…
मार्टिन स्पैमर

5
राज्य डिजाइन पैटर्न (उदाहरण के लिए) आमतौर पर एक संदर्भ वर्ग और एक राज्य इंटरफ़ेस के साथ लागू किया जाता है। राज्य के उदाहरणों को संदर्भ उदाहरण दिया जाता है ताकि वे सेटस्टेट कह सकें। इसके लिए राज्य को संदर्भ और इसके विपरीत के बारे में जानना आवश्यक है। यह शास्त्रीय निर्माण "कोड में खराब" कैसे हो रहा है? वास्तव में यही वह समस्या है जो मैं पाइथन के साथ कुश्ती कर रहा हूं, लेकिन जब मैंने जावा में स्टेट लागू किया था, तब ऐसा नहीं था।
शुभ अंक

141

जबकि आपको निश्चित रूप से परिपत्र निर्भरता से बचना चाहिए, आप अजगर में आयात को स्थगित कर सकते हैं।

उदाहरण के लिए:

import SomeModule

def someFunction(arg):
    from some.dependency import DependentClass

यह (कम से कम कुछ मामलों में) त्रुटि को दरकिनार करेगा।


38
वृत्ताकार निर्भरता को सबसे अच्छा
माना जाता है

4
Pep8 के आधार पर, आयात करने की विधि के अंदर अच्छा अभ्यास नहीं है
TomSawyer

@TomSawyer क्यों?
क्रॉव

@TomSawyer मैं इस अनुशंसा नहीं करते हैं, लेकिन यह एक त्वरित समाधान है कि आप एक बाँध से बाहर निकल सकते है
bharling

117

यह एक परिपत्र निर्भरता है। इसे बिना किसी संरचनात्मक संशोधनों के कोड में हल किया जा सकता है। समस्या तब होती है क्योंकि vectorआप मांग करते हैं कि entityतुरंत उपयोग के लिए उपलब्ध कराया जाए, और इसके विपरीत। इस समस्या का कारण यह है कि आप तैयार होने से पहले मॉड्यूल की सामग्री का उपयोग करने के लिए कह रहे हैं - उपयोग करके from x import y। यह अनिवार्य रूप से के रूप में ही है

import x
y = x.y
del x

पायथन परिपत्र निर्भरता का पता लगाने और आयात के अनंत लूप को रोकने में सक्षम है। अनिवार्य रूप से यह सब होता है कि मॉड्यूल के लिए एक खाली प्लेसहोल्डर बनाया जाता है (अर्थात, इसकी कोई सामग्री नहीं है)। एक बार परिपत्र निर्भर मॉड्यूल संकलित किए जाने के बाद यह आयातित मॉड्यूल को अपडेट करता है। यह कुछ इस तरह से काम करता है।

a = module() # import a

# rest of module

a.update_contents(real_a)

अजगर के लिए परिपत्र निर्भरता के साथ काम करने में सक्षम होने के लिए आपको import xकेवल शैली का उपयोग करना होगा ।

import x
class cls:
    def __init__(self):
        self.y = x.y

चूंकि अब आप शीर्ष स्तर पर मॉड्यूल की सामग्री का उल्लेख नहीं कर रहे हैं, अजगर वास्तव में परिपत्र निर्भरता की सामग्री का उपयोग किए बिना मॉड्यूल को संकलित कर सकता है। शीर्ष स्तर से मेरा मतलब उन पंक्तियों से है जिन्हें संकलन के दौरान कार्यों की सामग्री के विपरीत निष्पादित किया जाएगा (जैसे। y = x.y)। मॉड्यूल सामग्री तक पहुँचने वाले स्थिर या वर्ग चर भी समस्याएँ पैदा करेंगे।


24

तर्क को स्पष्ट करने के लिए बहुत महत्वपूर्ण है। यह समस्या दिखाई देती है, क्योंकि संदर्भ एक मृत लूप बन जाता है।

यदि आप तर्क को बदलना नहीं चाहते हैं, तो आप कुछ आयात विवरण रख सकते हैं, जो फ़ाइल की अन्य स्थिति में ImportError का कारण बनता है, उदाहरण के लिए अंत।

a.py

from test.b import b2

def a1():
    print('a1')
    b2()

b.py

from test.a import a1

def b1():
    print('b1')
    a1()

def b2():
    print('b2')

if __name__ == '__main__':
    b1()

आपको आयात त्रुटि मिलेगी: ImportError: cannot import name 'a1'

लेकिन अगर हम नीचे से A की तरह test.b आयात b2 से स्थिति बदलते हैं:

a.py

def a1():
    print('a1')
    b2()

from test.b import b2

और हम जो चाहते हैं वह पा सकते हैं:

b1
a1
b2

18

यह एक परिपत्र निर्भरता है। हम आयात मॉड्यूल या वर्ग या फ़ंक्शन का उपयोग करके इस समस्या को हल कर सकते हैं जहां हमें आवश्यकता थी। यदि हम इस दृष्टिकोण का उपयोग करते हैं, तो हम परिपत्र निर्भरता को ठीक कर सकते हैं

A.py

from B import b2
def a1():
    print('a1')
    b2()

B.py

def b1():
   from A import a1
   print('b1')
   a1()

def b2():
   print('b2')
if __name__ == '__main__':
   b1() 

17

मुझे सिर्फ यह त्रुटि मिली है, एक अलग कारण के लिए ...

from my_sub_module import my_function

मुख्य स्क्रिप्ट में विंडोज लाइन एंडिंग थी। my_sub_moduleUNIX लाइन अंत था। उन्हें बदलने के लिए एक ही समस्या तय की जा रही है। उन्हें समान वर्ण एन्कोडिंग की भी आवश्यकता है।


7

जैसा कि पहले ही उल्लेख किया गया है, यह एक परिपत्र निर्भरता के कारण होता है । क्या उल्लेख नहीं किया गया है कि जब आप अजगर का उपयोग कर रहे है टाइपिंग मॉड्यूल और आप एक वर्ग केवल टिप्पणी करने के लिए प्रयोग की जाने वाली आयात प्रकार , आप उपयोग कर सकते हैं आगे संदर्भ :

जब एक प्रकार के संकेत में ऐसे नाम होते हैं जिन्हें अभी तक परिभाषित नहीं किया गया है, तो उस परिभाषा को एक स्ट्रिंग शाब्दिक के रूप में व्यक्त किया जा सकता है, जिसे बाद में हल किया जा सकता है।

और इसके बजाय निर्भरता ( आयात ) को हटा दें

from my_module import Tree

def func(arg: Tree):
    # code

करना:

def func(arg: 'Tree'):
    # code

(हटाए गए importबयान पर ध्यान दें )


6

अपने वर्तमान अजगर स्क्रिप्ट का नाम कुछ अन्य मॉड्यूल के नाम के साथ न रखें जो आप आयात करते हैं

समाधान: अपने काम करने वाले अजगर लिपि का नाम बदलें

उदाहरण:

  1. आप काम कर रहे हैं medicaltorch.py
  2. उस स्क्रिप्ट में, आपके पास: from medicaltorch import datasets as mt_datasetsजहां medicaltorchएक स्थापित मॉड्यूल माना जाता है

इस के साथ विफल हो जाएगा ImportError। बस 1 में अपने कामकाजी अजगर स्क्रिप्ट का नाम बदलें।


धन्यवाद, यह उस समस्या को हल करता है जो मेरे पास थी। मैंने colorama लाइब्रेरी का उपयोग किया और फ़ाइल colorama.py नाम दिया, इसलिए अजगर को पता नहीं था कि क्या आयात करना है। फ़ाइल नाम बदलने से मदद मिलती है।
मारेक बोडज़ियोनी

5

इसे अभी तक यहां न देखें - यह अविश्वसनीय रूप से बेवकूफ है, लेकिन सुनिश्चित करें कि आप सही चर / फ़ंक्शन आयात कर रहे हैं।

मुझे यह त्रुटि मिल रही थी

ImportError: IMPLICIT_WAIT नाम आयात नहीं कर सकता

क्योंकि मेरा चर वास्तव में था IMPLICIT_TIMEOUT

जब मैंने सही नाम का उपयोग करने के लिए अपना आयात बदल दिया, तो मुझे अब त्रुटि नहीं मिली


1
मैं किसी को मारने की कोशिश करने के लिए तैयार था कि from PIL import Pillowवह काम क्यों नहीं कर रहा था। 😠
आलाप

5

आप आयात कर रहे हैं file1.pyसे file2.pyहै और इस प्रयोग किया है:

if __name__ == '__main__':
    # etc

नीचे चर कि file1.py आयात नहीं किया जा सकता है file2.pyक्योंकि __name__ बराबर नहीं है __main__ !

आप से कुछ आयात करना चाहते हैं file1.pyके लिए file2.py, आप में इस का उपयोग करने की आवश्यकता है file1.py:

if __name__ == 'file1':
    # etc

संदेह के मामले में, assertअगर यह निर्धारित करने के लिए एक बयान करें__name__=='__main__'


4

आयात त्रुटि ट्रैक करने का एक तरीका चरणबद्ध तरीके से है कि आयातित फ़ाइलों में से प्रत्येक पर पायथन को चलाने की कोशिश की जाए ताकि खराब को ट्रैक किया जा सके।

  1. आपको कुछ ऐसा मिलता है:

    python ./main.py

    ImportError: नाम A को आयात नहीं कर सकता

  2. फिर आप लॉन्च करें:

    python ./modules/a.py

    ImportError: B नाम आयात नहीं कर सकता

  3. फिर आप लॉन्च करें:

    python ./modules/b.py

    ImportError: नाम C (कुछ गैर मौजूदा मॉड्यूल या कुछ अन्य त्रुटि) आयात नहीं कर सकता


3

ओपी के लिए भी सीधे प्रासंगिक नहीं है, लेकिन एक PyCharm पायथन कंसोल को पुनः आरंभ करने में विफल होने के बाद, एक मॉड्यूल में एक नई वस्तु जोड़ने के बाद, एक बहुत ही भ्रमित करने का एक शानदार तरीका हैImportError: Cannot import name ...

भ्रामक हिस्सा यह है कि PyCharm कंसोल में आयात को स्वत: पूर्ण कर देगा , लेकिन फिर आयात विफल हो जाता है।


2

मेरे मामले में, मैं एक ज्यूपिटर नोटबुक में काम कर रहा था और यह तब हो रहा था क्योंकि जब मैं अपनी वर्किंग फाइल के अंदर क्लास / फंक्शन को परिभाषित करता था तो पहले से ही आयात किया जा रहा था।

मैंने अपना ज्यूपिटर कर्नेल फिर से शुरू किया और त्रुटि गायब हो गई।


1

विशेष रूप से इस पूछने वाले के लिए नहीं, लेकिन यह वही त्रुटि दिखाएगा यदि आपके आयात में वर्ग का नाम उस फ़ाइल में परिभाषा से मेल नहीं खाता है जिसे आप आयात कर रहे हैं।


1

समस्या स्पष्ट है: में और मॉड्यूल में नामों के बीच परिपत्र निर्भरताentityphysics

पूरे मॉड्यूल या सिर्फ एक वर्ग को आयात करने के बावजूद, नाम लोड किए जाने चाहिए।

इस उदाहरण को देखें:

# a.py
import b
def foo():
  pass
b.bar()
# b.py
import a
def bar():
  pass
a.foo()

इसमें संकलित किया जाएगा:

# a.py
# import b
# b.py
# import a # ignored, already importing
def bar():
  pass
a.foo()
# name a.foo is not defined!!!
# import b done!
def foo():
  pass
b.bar()
# done!

एक मामूली बदलाव के साथ हम इसे हल कर सकते हैं:

# a.py
def foo():
  pass
import b
b.bar()
# b.py
def bar():
  pass
import a
a.foo()

इसमें संकलित किया जाएगा:

# a.py
def foo():
  pass
# import b
# b.py
def bar():
  pass
# import a # ignored, already importing
a.foo()
# import b done!
b.bar()
# done!
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.