আমদানি ত্রুটি: এক্স নাম আমদানি করা যায় না


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.

আমি তখন মেইন.পি থেকে চালাচ্ছি এবং আমি নিম্নলিখিত ত্রুটিটি পেয়েছি:

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
পাইথনে লুপ-আমদানির জন্য এই উত্তরটি দেখুন: স্ট্যাকওভারফ্লো.com
গ্রেগোর

সাধারণভাবে, এটি করা ভাল কোডিং অনুশীলন নয় from <module> import <name>, বা from <modlue> import *। অনুরূপ নামযুক্ত রেফারেন্সগুলিকে ওভাররাইটিংয়ের সম্ভাবনা রোধ করতে মডিউল নেমস্পেসের অধীনে আমদানি করা আরও ভাল।
জোয়েল করনেট

1
@ জেসেলস আপনার কেবলমাত্র ক্লাসে কল করা উচিত Entityএবং এর Vectorপরিবর্তে Entএবং এই Vectজাতীয় নামগুলি ছোট করার কোনও কারণ নেই। এবং হ্যাঁ, import vectorএবং তারপর ব্যবহার করুন x = vector.Vector(0,0,0)

7
আরে @ কেভিন আপনি যেহেতু জাভা আরও ভাল জানেন, তাই আপনার এই ২০০৮ সালের নিবন্ধটি সম্পর্কে কী ধারণা রয়েছে যেখানে লেখকের প্রথম বাক্যটি জাভায় বিজ্ঞপ্তি নির্ভরতা "বেশ সাধারণ অনুশীলন" কীভাবে বোঝায় ?
আরেওয়াচ এই

উত্তর:


502

আপনার বিজ্ঞপ্তি নির্ভর আমদানি রয়েছে। শ্রেণি সংজ্ঞায়িত হওয়ার আগে physics.pyথেকেই আমদানি করা হয় এবং ইতিমধ্যে শুরু হওয়া আমদানির চেষ্টা করে । মডিউল থেকে নির্ভরতা সরান ।entityEntphysicsentityphysicsentity


5
আপনার কোডটি রিফ্যাক্টর করার চেয়ে বেশি কিছু করার নেই। যদি আপনি এনটি এর নীচে কেবল এনট কনস্ট্রাক্টর সংজ্ঞা মুভ এমপোর্টে পদার্থবিজ্ঞান উল্লেখ না করেন। আপনি যদি করেন তবে কনস্ট্রাক্টরের পরে আমদানি সক্ষম করতে সেটফিজিক্সের মতো পদ্ধতি যুক্ত করুন।
তিমু ইকোনেন

12
@ জেসেলস যেহেতু আপনি দীর্ঘ সময় ধরে সি ++ নিয়ে কাজ করেছেন, আপনার জানা উচিত যে দুটি ক্লাস কখনও একে অপরের উপর নির্ভরশীল নয়। এটি সি ++ এ অত্যন্ত গুরুত্বপূর্ণ এবং এটি পাইথনের # 1 জিনিস না হলেও এই নিয়মটি অনুসরণ করা এখনও সত্যই ভাল ধারণা। কখনও কখনও দুটি ক্লাস যা একে অপরকে চেনে না। আপনার ক্লাসগুলির জন্য কাঠামো তৈরিতে আপনার যদি সহায়তা প্রয়োজন হয় তবে কোডের বাকি অংশও পোস্ট করুন। কিভাবে ঠিক (কোড পদ হয় না) Entityএবং Physicsএকে অপরের সাথে যুক্ত? আমি নিশ্চিত যে আপনি যা করার চেষ্টা করছেন তার একটি কার্যকারিতা রয়েছে।

7
@ ব্যবহারকারী2032433 এটি 'একে অপরকে জানুন' বলতে আপনি যা বোঝাতে চেয়েছেন তা নির্ভর করে। এটি সত্য যে ভাল নকশা সাধারণত একমুখী নির্ভরতার গাছ উত্পন্ন করে এবং এটি সাধারণত সর্বোত্তম পন্থা। তবে এর ব্যতিক্রমও রয়েছে। সি ++ ক্লাস অবশ্যই একে অপরকে বৃত্তাকারে উল্লেখ করতে পারে। (যদিও তাদের পক্ষে একে অপরের সমন্বয়ে গঠিত হওয়া অসম্ভব)) ফরোয়ার্ড-ঘোষণা ছাড়াই, পাইথনের এটি একটি সমস্যা যা সর্বদা একটি সি ++ সমাধান করে না।
জন ম্যাকফার্লেন

93
বিবৃতিটি "দুটি শ্রেণির উচিত একে অপরের উপর নির্ভরশীল হওয়া উচিত না" জঞ্জাল is দ্বি-দিক (দ্বি নির্দেশমূলক) নেভিগেশন অবজেক্ট অরিয়েন্টেশনে খুব সাধারণ। books.google.co.uk/...
মার্টিন Spamer

5
রাজ্যের নকশা প্যাটার্ন (উদাহরণস্বরূপ) সাধারণত একটি প্রাসঙ্গিক শ্রেণি এবং একটি রাজ্য ইন্টারফেস সহ প্রয়োগ করা হয়। রাজ্যের উদাহরণগুলি প্রসঙ্গের উদাহরণটি পাস হয়ে যায় যাতে তারা সেটস্টেটকে কল করতে পারে। এটিকে প্রসঙ্গ এবং তদ্বিপরীত সম্পর্কে রাষ্ট্রের জানা প্রয়োজন। এই ধ্রুপদী নির্মাণটি কীভাবে "কোডে খারাপ" হচ্ছে? আসলে পাইথনের সাথে আমি কুস্তি করছি ঠিক এটাই সমস্যা, তবে আমি জাভাতে রাজ্য প্রয়োগ করার সময় হয়নি।
শুভারম্ভ

141

আপনার অবশ্যই বৃত্তাকার নির্ভরতা এড়ানো উচিত, আপনি অজগর থেকে আমদানি স্থগিত করতে পারেন।

উদাহরণ স্বরূপ:

import SomeModule

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

এটি (কমপক্ষে কিছু ক্ষেত্রে) ত্রুটিটি বিঘ্নিত করবে।


38
বিজ্ঞপ্তি নির্ভরতা সেরা
পরিলক্ষিত হয়

4
পেপ 8-এর ভিত্তিতে, আমদানি পদ্ধতির অভ্যন্তরে
রাখাই

@ টমসওয়ের কেন?
ক্রু

@ টমশায়ার আমি এটির প্রস্তাব দিচ্ছি না, তবে এটি একটি দ্রুত সমাধান যা আপনাকে একটি বাঁধাই থেকে মুক্ত করতে পারে
ভরালিং

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

যুক্তি পরিষ্কার করতে খুব গুরুত্বপূর্ণ। এই সমস্যাটি উপস্থিত হয়, কারণ রেফারেন্সটি একটি মৃত লুপে পরিণত হয়।

আপনি যদি যুক্তিটি পরিবর্তন করতে না চান, আপনি কিছু আমদানি বিবৃতি রাখতে পারেন যা আমদানি ত্রুটির কারণে ফাইলের অন্য অবস্থানে পরিণত হয়েছিল, উদাহরণস্বরূপ শেষ।

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'

তবে আমরা যদি টেস্ট.বি থেকে অবস্থানটি পরিবর্তন করি তবে নীচের মতো একটিতে বি 2 আমদানি করুন:

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_moduleইউনিক্স লাইনের শেষ ছিল। এগুলি একই হিসাবে পরিবর্তন করা সমস্যার সমাধান করে। তাদের একই চরিত্রের এনকোডিং হওয়া দরকার।


6

আপনার আমদানি করা কিছু অন্যান্য মডিউলের নামের সাথে আপনার বর্তমান পাইথন স্ক্রিপ্টটির নাম রাখবেন না

সমাধান: আপনার কার্যকরী অজগর স্ক্রিপ্টটির নামকরণ করুন

উদাহরণ:

  1. আপনি কাজ করছেন medicaltorch.py
  2. সেই স্ক্রিপ্টে, আপনার কাছে রয়েছে: from medicaltorch import datasets as mt_datasetsযেখানে medicaltorchএকটি ইনস্টলড মডিউল হওয়ার কথা

এটি এর সাথে ব্যর্থ হবে ImportError। কেবলমাত্র আপনার ওয়ার্কিং পাইথন স্ক্রিপ্টটির নাম পরিবর্তন করুন ১৯৯। সালে।


ধন্যবাদ, এটি আমার যা সমস্যা ছিল তা সমাধান করে। আমি কলোরামা লাইব্রেরি ব্যবহার করেছি এবং নাম কলারোমা.পি ফাইল রেখেছি তাই পাইথন আমদানি করতে জানত না। ফাইলের নাম পরিবর্তন করা সহায়তা করে।
মারেক বোডজিওনি

6

ইতিমধ্যে উল্লিখিত হিসাবে, এটি একটি বিজ্ঞপ্তি নির্ভরতার কারণে ঘটে । যা উল্লেখ করা হয়নি তা হ'ল আপনি যখন পাইথন টাইপিং মডিউলটি ব্যবহার করেন এবং আপনি কেবল প্রকারগুলি বর্নিত করতে কোনও ক্লাস আমদানি করেন আপনি ফরোয়ার্ড উল্লেখগুলি ব্যবহার করতে পারেন :

যখন কোনও প্রকার ইঙ্গিতটিতে এমন নাম থাকে যা এখনও সংজ্ঞায়িত হয়নি, তখন সেই সংজ্ঞাটি স্ট্রিং আক্ষরিক হিসাবে প্রকাশ করা হতে পারে, পরে সমাধান হতে পারে।

এবং নির্ভরতা ( আমদানি ) সরান , উদাহরণস্বরূপ পরিবর্তে

from my_module import Tree

def func(arg: Tree):
    # code

একটি করুন:

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

(সরানো importবিবৃতি নোট করুন )


5

এটি এখানে এখনও দেখবেন না - এটি অবিশ্বাস্যভাবে বোকা, তবে আপনি সঠিক ভেরিয়েবল / ফাংশনটি আমদানি করছেন তা নিশ্চিত করুন।

আমি এই ত্রুটি পেয়েছিলাম

আমদানি ত্রুটি: IMPLICIT_WAIT নাম আমদানি করতে পারে না

আমার পরিবর্তনশীল আসলে ছিল IMPLICIT_TIMEOUT

আমি যখন সঠিক নামটি ব্যবহার করতে আমার আমদানি পরিবর্তন করেছি তখন আর ত্রুটিটি পাই নি ♂️‍♂️ ♂️


1
আমি from PIL import Pillowকাজ করছি না কেন তা চেষ্টা করার জন্য কাউকে হত্যা করতে প্রস্তুত ছিলাম। 😠
aalaap

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নির্ধারণ করার জন্য একটি বিবৃতি দিন make__name__=='__main__'


4

আমদানি ত্রুটি ট্র্যাক করার একটি উপায় হ'ল ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে ধাপে চালিত করার জন্য প্রতিটি আমদানি করা ফাইলের উপর অজগর চালানো।

  1. আপনি কিছু পেতে:

    python ./main.py

    আমদানি ত্রুটি: নামটি আমদানি করতে পারে না

  2. তারপরে আপনি চালু করুন:

    python ./modules/a.py

    আমদানি ত্রুটি: নাম বি আমদানি করতে পারে না

  3. তারপরে আপনি চালু করুন:

    python ./modules/b.py

    আমদানি ত্রুটি: নাম সি (কিছু নন-বিদ্যমান মডিউল বা অন্য কোনও ত্রুটি) আমদানি করতে পারে না


3

এছাড়াও ওপির সাথে সরাসরি প্রাসঙ্গিক নয়, তবে মডিউলে একটি নতুন অবজেক্ট যুক্ত করার পরে পাইচর্ম পাইথন কনসোলটি পুনরায় চালু করতে ব্যর্থ হওয়াও একটি খুব বিভ্রান্ত হওয়ার দুর্দান্ত উপায় isImportError: Cannot import name ...

বিভ্রান্তিকর অংশটি হল যে পাইচার্ম কনসোলে আমদানিটি স্বতঃপূরণ করবে , তবে আমদানি ব্যর্থ হয়।


2

আমার ক্ষেত্রে, আমি একটি জপিটার নোটবুকে কাজ করছিলাম এবং যখন আমি আমার ওয়ার্কিং ফাইলে শ্রেণি / ফাংশনটি সংজ্ঞায়িত করেছি তখন থেকেই আমদানিটি ইতিমধ্যে ক্যাশে হওয়ার কারণে ঘটছিল।

আমি আমার জুপিটার কার্নেলটি আবার চালু করেছি এবং ত্রুটিটি অদৃশ্য হয়ে গেছে।


1

এই প্রশ্নকারীর জন্য বিশেষভাবে নয়, তবে আপনার আমদানিতে শ্রেণীর নামটি আপনি যে ফাইল থেকে আমদানি করছেন ফাইলের সংজ্ঞাটির সাথে মেলে না তবে এই একই ত্রুটিটি প্রদর্শিত হবে।


1

সমস্যা স্পষ্ট: বৃত্তাকার নির্ভরতা নাম মধ্যে entityএবংphysics মডিউলগুলির ।

পুরো মডিউল বা কেবল একটি শ্রেণি আমদানি করা নির্বিশেষে, নামগুলি বোঝা আবশ্যক।

এই উদাহরণটি দেখুন:

# 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!
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.