বৃত্তাকার (বা চক্র) পাইথনে আমদানি করে


351

দুটি মডিউল একে অপরকে আমদানি করলে কী হবে?

সমস্যাটি সাধারণ করতে, পাইথনের চক্রীয় আমদানি সম্পর্কে কী?



1
এছাড়াও কেবল একটি রেফারেন্স হিসাবে, মনে হয় বৃত্তাকার আমদানি অজগর 3.5 (এবং সম্ভবত এর বাইরে) এ অনুমোদিত কিন্তু 3.4 নয় (এবং সম্ভবত বেলো)।
চার্লি পার্কার

4
আমি পাইথন ৩.7.২ ব্যবহার করছি এবং বিজ্ঞপ্তি নির্ভরতার কারণে এখনও রানটাইম ত্রুটি করছি।
রিচার্ড হোয়াইটহেড

উত্তর:


280

গত বছর comp.lang.python এ এ নিয়ে সত্যিই একটি ভাল আলোচনা হয়েছিল । এটি আপনার প্রশ্নের সুন্দর উত্তর দেয়।

আমদানি সত্যিই বেশ সোজা। শুধু নিম্নলিখিত মনে রাখবেন:

'ইম্পোর্ট' এবং 'এক্সএক্সএক্সএক্স ইম্পোর্ট ইয়ে' থেকে এক্সিকিউটেবল স্টেটমেন্ট। চলমান প্রোগ্রামটি line লাইনে পৌঁছালে তারা কার্যকর করে।

যদি কোনও মডিউল sys.modules এ না থাকে, তবে একটি আমদানি sys.modules এ নতুন মডিউল এন্ট্রি তৈরি করে এবং তারপরে মডিউলটিতে কোডটি কার্যকর করে। কার্যকর করা শেষ না হওয়া পর্যন্ত এটি কলিং মডিউলে নিয়ন্ত্রণ ফিরিয়ে দেয় না।

যদি মডিউলটি সিস.মডিউলগুলিতে বিদ্যমান থাকে তবে কোনও আমদানি কেবল কার্যকরভাবে সম্পন্ন হয়েছে কিনা তা মডিউলটি দেয়। এই কারণেই সাইক্লিক আমদানি মডিউলগুলি আংশিক খালি মনে হতে পারে।

অবশেষে, নির্বাহী স্ক্রিপ্টটি __main__ নামক একটি মডিউলে চলে, তার নিজের নামে স্ক্রিপ্টটি আমদানি করা __main__ এর সাথে সম্পর্কযুক্ত একটি নতুন মডিউল তৈরি করবে।

অনেকগুলি একসাথে নিয়ে যান এবং মডিউলগুলি আমদানি করার সময় আপনার কোনও আশ্চর্য হওয়া উচিত নয়।


13
@ meawoppl আপনি এই মন্তব্যটি প্রসারিত করতে পারেন, দয়া করে? তারা কীভাবে বিশেষভাবে পরিবর্তিত হয়েছে?
ড্যান শ্যাচিন

3
এখন অবধি, পাইথন 3-তে বৃত্তাকার আমদানির একমাত্র রেফারেন্স "নতুন কী?" পৃষ্ঠাগুলি 3.5 একটিতে আছে । এটি বলে যে "আপেক্ষিক আমদানি জড়িত বিজ্ঞপ্তি আমদানি এখন সমর্থিত"। @ মায়োপ্পল এই পৃষ্ঠাগুলিতে তালিকাভুক্ত নয় এমন আরও কিছু খুঁজে পেয়েছেন?
zizollo

4
তারা ডিএফ। 3.0.3.4 এ সমর্থিত নয়। বা কমপক্ষে সাফল্যের জন্য শব্দার্থবিজ্ঞান আলাদা। এখানে একটি সংক্ষিপ্তসার আমি পেয়েছি যে 3.5 পরিবর্তনগুলি উল্লেখ করে না n't gist.github.com/datagrok/40bf84d5870c41a77dc6
meawoppl

দয়া করে আপনি এটিতে প্রসারিত করতে পারেন "অবশেষে, এক্সিকিউটিভ স্ক্রিপ্টটি মূল নামে একটি মডিউলে চলে , তার নিজের নামে স্ক্রিপ্ট আমদানি করা একটি নতুন মডিউলটি মূল সাথে সম্পর্কিত নয় " " সুতরাং আসুন বলি যে ফাইলটি a.py এবং যখন এটি প্রধান এন্ট্রি পয়েন্ট হিসাবে সঞ্চালিত হয়, তবে এটি এখন প্রধান এটি যদি কোনও ইমপোর্ট থেকে কিছু ভেরিয়েবলের মতো কোড থাকে। তারপরে কি একই ফাইল 'a.py' sys মডিউল টেবিলে লোড হবে? সুতরাং এর অর্থ কি এটি যদি প্রিন্ট স্টেটমেন্ট বলে থাকে তবে এটি দুটিবার চলবে? একবার মূল ফাইলের জন্য এবং আবার যখন আমদানির মুখোমুখি হয়?
পরিবর্তনশীল

এই উত্তরটি 10 ​​বছর পুরনো, এবং পাইথন, ২.x বা 3.x এর বিভিন্ন সংস্করণে এটি সঠিক রয়ে গেছে তা নিশ্চিত করার জন্য আমি একটি আধুনিকীকরণের আপডেট চাই
ফলেনরেপার

296

আপনি যদি import fooভিতরে barএবং import barভিতরে করেন তবে fooএটি দুর্দান্ত কাজ করবে। আসলে কোনও কিছু চলার সময় উভয় মডিউল পুরোপুরি লোড হয়ে যাবে এবং একে অপরের সাথে উল্লেখ থাকবে।

সমস্যাটি হ'ল পরিবর্তে আপনি যখন করেন from foo import abcএবং করেন from bar import xyz। কারণ এখন প্রতিটি মডিউলকে আমদানি করার আগেই অন্য মডিউলটি ইতিমধ্যে আমদানি করা প্রয়োজন (যাতে আমরা যে নামটি আমদানি করছি তা বিদ্যমান রয়েছে)।


27
এটি মনে হয় from foo import *এবং from bar import *ভাল কাজ করবে।
আকাওয়াল

1
A.py/b.py ব্যবহার করে উপরের পোস্টে সম্পাদনা পরীক্ষা করুন। তিনি ব্যবহার করেন না from x import y, এবং তবুও বিজ্ঞপ্তি আমদানির ত্রুটিটি পেয়েছে
গ্রেগ এনিস

2
এই সম্পূর্ণ সত্য নয়। ঠিক যেমন থেকে আমদানি করুন *, আপনি যদি শীর্ষ স্তরের বৃত্তাকার আমদানিতে কোনও উপাদান অ্যাক্সেস করার চেষ্টা করে থাকেন, সুতরাং স্ক্রিপ্টটি রান শেষ করার আগে, আপনার একই সমস্যা থাকবে। উদাহরণস্বরূপ আপনি যদি অন্য কোনও প্যাকেজে কোনও প্যাকেজ বিশ্বব্যাপী সেট করে থাকেন এবং তারা উভয়ই একে অপরকে অন্তর্ভুক্ত করে। বেস ক্লাসে এমন একটি অবজেক্টের জন্য একটি opালু কারখানা তৈরি করার জন্য আমি এটি করছিলাম যেখানে sub বস্তুটি বেশ কয়েকটি সাবক্লাসের মধ্যে একটি হতে পারে এবং ব্যবহার কোডটি সচেতন হওয়ার প্রয়োজন ছিল না যা এটি আসলে তৈরি করছে।
অ্যারোনম্যান

3
@ আকাওয়াল আসলেই নয়। এটি কেবলমাত্র নামগুলি আমদানি করবে যখন importবিবৃতি কার্যকর করা হয়। সুতরাং এটি ত্রুটিযুক্ত হবে না তবে আপনি যে ভেরিয়েবলগুলি প্রত্যাশা করেছেন তা পেতে পারেন না।
আগস্ট

3
দ্রষ্টব্য, আপনি যদি করেন from foo import *এবং from bar import *, এর মধ্যে কার্যকর করা সমস্ত fooকিছুই প্রাথমিক পর্যায়ে রয়েছে barএবং এর আসল ফাংশনগুলি barএখনও সংজ্ঞায়িত হয়নি ...
মার্টিয়ান2049

100

চক্রীয় আমদানি সমাপ্ত হয়, তবে আপনাকে মডিউল শুরুর সময় চক্রাকারে-আমদানি করা মডিউলগুলি ব্যবহার না করার বিষয়ে সতর্কতা অবলম্বন করা উচিত।

নিম্নলিখিত ফাইলগুলি বিবেচনা করুন:

a.py:

print "a in"
import sys
print "b imported: %s" % ("b" in sys.modules, )
import b
print "a out"

b.py:

print "b in"
import a
print "b out"
x = 3

আপনি যদি a.py কার্যকর করেন তবে আপনি নিম্নলিখিতগুলি পাবেন:

$ python a.py
a in
b imported: False
b in
a in
b imported: True
a out
b out
a out

বি.পি.-এর দ্বিতীয় আমদানিতে (দ্বিতীয়টিতে a in) পাইথন ইন্টারপ্রেটার bআবার আমদানি করে না , কারণ এটি মডিউল ডেকে ইতিমধ্যে বিদ্যমান।

আপনি যদি মডিউল শুরুর সময় b.xথেকে অ্যাক্সেস করার চেষ্টা করেন তবে আপনি aএকটি পাবেন AttributeError

নিম্নলিখিত লাইন এতে যুক্ত করুন a.py:

print b.x

তারপরে, আউটপুটটি হ'ল:

$ python a.py
a in                    
b imported: False
b in
a in
b imported: True
a out
Traceback (most recent call last):
  File "a.py", line 4, in <module>
    import b
  File "/home/shlomme/tmp/x/b.py", line 2, in <module>
    import a
 File "/home/shlomme/tmp/x/a.py", line 7, in <module>
    print b.x
AttributeError: 'module' object has no attribute 'x'

এটি কারণ আমদানিতে মডিউলগুলি কার্যকর করা হয় এবং সেই সময়ে b.xঅ্যাক্সেস করা হয়, লাইনটি x = 3এখনও কার্যকর করা হয়নি যা কেবল পরে ঘটবে b out


14
এটি সমস্যার ব্যাপকভাবে ব্যাখ্যা করে, তবে কীভাবে সমাধান হবে? আমরা কীভাবে সঠিকভাবে এক্স আমদানি এবং মুদ্রণ করতে পারি? উপরের অন্যান্য সমাধানগুলি আমার পক্ষে কার্যকর হয়নি
মেহমেট

আমি মনে করি আপনি যদি এর __name__পরিবর্তে ব্যবহার করেন তবে এই উত্তরটি অনেক উপকৃত হবে 'a'। শুরুতে, আমি সম্পূর্ণ বিভ্রান্ত হয়ে পড়েছিলাম কেন একটি ফাইল দু'বার কার্যকর করা হবে।
বার্গি

30

অন্যান্য উত্তরগুলির বর্ণনা হিসাবে এই ধরণটি অজগরটিতে গ্রহণযোগ্য:

def dostuff(self):
     from foo import bar
     ...

যা যখন ফাইলটি অন্য মডিউল দ্বারা আমদানি করা হয় তখন আমদানির বিবৃতি কার্যকর করতে এড়াতে পারে। একটি লজিকাল বিজ্ঞপ্তি নির্ভরতা থাকলেই এটি ব্যর্থ হবে।

বেশিরভাগ সার্কুলার আমদানি আসলে যৌক্তিক বিজ্ঞপ্তি আমদানি নয় বরং ImportErrorত্রুটি বাড়াতে import()ডেকে আনা হয় কারণ ডাকা হওয়ার সময় পুরো ফাইলটির শীর্ষ স্তরের বিবৃতি মূল্যায়ন করে।

ImportErrorsযদি আপনি ইতিমধ্যে ইতিমধ্যে আপনার আমদানি চান তবে এগুলি প্রায়শই এড়ানো যায় :

এই বিজ্ঞপ্তি আমদানি বিবেচনা করুন:

অ্যাপ এ

# profiles/serializers.py

from images.serializers import SimplifiedImageSerializer

class SimplifiedProfileSerializer(serializers.Serializer):
    name = serializers.CharField()

class ProfileSerializer(SimplifiedProfileSerializer):
    recent_images = SimplifiedImageSerializer(many=True)

অ্যাপ বি

# images/serializers.py

from profiles.serializers import SimplifiedProfileSerializer

class SimplifiedImageSerializer(serializers.Serializer):
    title = serializers.CharField()

class ImageSerializer(SimplifiedImageSerializer):
    profile = SimplifiedProfileSerializer()

ডেভিড বিজলিজ থেকে দুর্দান্ত টক মডিউল এবং প্যাকেজগুলি: লাইভ এবং লেট ডাই! - পাইকন 2015 , 1:54:00এখানে পাইথনের বৃত্তাকার আমদানি মোকাবেলার একটি উপায়:

try:
    from images.serializers import SimplifiedImageSerializer
except ImportError:
    import sys
    SimplifiedImageSerializer = sys.modules[__package__ + '.SimplifiedImageSerializer']

এটি আমদানির চেষ্টা করে SimplifiedImageSerializerএবং যদি ImportErrorউত্থাপিত হয়, কারণ এটি ইতিমধ্যে আমদানি করা হয়েছে, এটি এটিকে আমদানি ক্যাশে থেকে টানবে।

পিএস: আপনাকে ডেভিড বেজলির কণ্ঠে এই পুরো পোস্টটি পড়তে হবে।


9
মডিউল ইতিমধ্যে আমদানি করা থাকলে আমদানি ত্রুটি উত্থাপিত হয় না। মডিউলগুলি আপনি যতবার ইম্পোর্ট করতে পারেন অর্থাত "ইম্পোর্ট এ; ইম্পোর্ট এ;" ঠিক আছে
ইউরাস

9

আমি এখানে একটি উদাহরণ পেয়েছি যা আমাকে আঘাত করেছে!

foo.py

import bar

class gX(object):
    g = 10

bar.py

from foo import gX

o = gX()

main.py

import foo
import bar

print "all done"

কমান্ড লাইনে: y পাইথন মেইন.পি

Traceback (most recent call last):
  File "m.py", line 1, in <module>
    import foo
  File "/home/xolve/foo.py", line 1, in <module>
    import bar
  File "/home/xolve/bar.py", line 1, in <module>
    from foo import gX
ImportError: cannot import name gX

2
আপনি কিভাবে এটি ঠিক করেছেন? আমি আমার নিজের একটি সমস্যা ঠিক করার জন্য বিজ্ঞপ্তি আমদানি বোঝার চেষ্টা করছি যা আপনি যা করছেন তার সাথে খুব মিল দেখাচ্ছে ...
c089

12
এরম ... আমি মনে করি আমি এই সমস্যাটিকে অবিশ্বাস্যভাবে কুরুচিপূর্ণ হ্যাক দিয়ে সমাধান করেছি। ys {{sys.modules- এ 'foo.bar' না থাকলে: foo আমদানি বার থেকে অন্য: বার = sys.modules ['foo.bar']}} I ব্যক্তিগতভাবে, আমি মনে করি বিজ্ঞপ্তি আমদানিগুলি খারাপ কোডে একটি বিশাল সতর্কতা চিহ্ন ডিজাইন ...
c089

5
@ c089, অথবা আপনি শুধু সরাতে পারে import barমধ্যে foo.pyথেকে শেষ
warvariuc

5
যদি barএবং fooউভয়ই অবশ্যই ব্যবহার করে gXতবে 'পরিষ্কার' সমাধানটি gXঅন্য মডিউলে রাখা এবং উভয়ই রাখা fooএবং barসেই মডিউলটি আমদানি করা। (কোনও লুক্কায়িত শব্দার্থ নির্ভরতা নেই এই অর্থে পরিচ্ছন্ন
Tim

2
টিম একটি ভাল পয়েন্ট আছে। মূলত এটি হ'ল barএমনকি gXফুওকেও খুঁজে পাচ্ছে না। বিজ্ঞপ্তি আমদানি নিজেই সূক্ষ্ম, তবে এটি gXযখন আমদানি করা হয় তখন এটি সংজ্ঞায়িত হয় না।
মার্টিয়ান2049

9

মডিউল a.py:

import b
print("This is from module a")

মডিউল বি.পি.

import a
print("This is from module b")

"মডিউল এ" চালানো আউটপুট আসবে:

>>> 
'This is from module a'
'This is from module b'
'This is from module a'
>>> 

বিজ্ঞপ্তি আমদানির কারণে অনন্তর আউটপুট দেওয়ার সময় এটি এই 3 টি লাইন আউটপুট দেয়। "মডিউল এ" চালানোর সময় লাইনে কী ঘটে তা এখানে তালিকাভুক্ত করা হয়েছে:

  1. প্রথম লাইন হয় import b। সুতরাং এটি মডিউল খ পরিদর্শন করবে
  2. মডিউল বি এর প্রথম লাইনটি হ'ল import a। সুতরাং এটি মডিউলটি পরিদর্শন করবে a
  3. মডিউলের প্রথম লাইনটি import bতবে নোট করুন যে এই লাইনটি আর কার্যকর করা হবে না , কারণ পাইথনের প্রতিটি ফাইল কেবল একবারের জন্য একটি আমদানি লাইন চালায়, এটি কোথায় বা কখন কার্যকর হয় তা বিবেচ্য নয়। সুতরাং এটি পরবর্তী লাইনে চলে যাবে এবং মুদ্রণ করবে "This is from module a"
  4. মডিউল বি থেকে পুরো মডিউলটি পরিদর্শন শেষে, আমরা এখনও মডিউল বিতে আছি। সুতরাং পরবর্তী লাইন মুদ্রণ করা হবে"This is from module b"
  5. মডিউল বি লাইন সম্পূর্ণরূপে কার্যকর করা হয়। সুতরাং আমরা মডিউলে ফিরে যাব যেখানে আমরা মডিউল শুরু করেছি খ।
  6. আমদানি বি লাইন ইতিমধ্যে কার্যকর করা হয়েছে এবং আবার কার্যকর করা হবে না। পরবর্তী লাইনটি মুদ্রণ করবে "This is from module a"এবং প্রোগ্রামটি শেষ হবে।

4

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

# Hack to import something without circular import issue
def load_module(name):
    """Load module using imp.find_module"""
    names = name.split(".")
    path = None
    for name in names:
        f, path, info = imp.find_module(name, path)
        path = [path]
    return imp.load_module(name, f, path[0], info)
constants = load_module("app.constants")

আবার এটি স্থায়ী সমাধান নয় তবে এমন কাউকে সহায়তা করতে পারে যে কোডের খুব বেশি পরিবর্তন না করেই আমদানি ত্রুটিটি ঠিক করতে চায়।

চিয়ার্স!


3

এখানে দুর্দান্ত উত্তর রয়েছে are সমস্যাটির দ্রুত সমাধানগুলির মধ্যে সাধারণত কিছু রয়েছে যাঁর মধ্যে কেউ কেউ অন্যের চেয়ে বেশি পাইথোনিক বোধ করেন, যদি আপনার কিছু রিফ্যাক্টরিং করার বিলাসিতা থাকে তবে অন্য পদ্ধতির মাধ্যমে আপনার কোডের সংগঠনটি বিশ্লেষণ করা হয় এবং বৃত্তাকার নির্ভরতা অপসারণ করার চেষ্টা করা হয়। উদাহরণস্বরূপ, আপনি এটি পেতে পারেন:

ফাইল a.py

from b import B

class A:
    @staticmethod
    def save_result(result):
        print('save the result')

    @staticmethod
    def do_something_a_ish(param):
        A.save_result(A.use_param_like_a_would(param))

    @staticmethod
    def do_something_related_to_b(param):
        B.do_something_b_ish(param)

ফাইল বি.পি.

from a import A

class B:
    @staticmethod
    def do_something_b_ish(param):
        A.save_result(B.use_param_like_b_would(param))

এই ক্ষেত্রে, কেবল একটি স্থিতিশীল পদ্ধতিকে একটি পৃথক ফাইলে সরানো, বলুন c.py:

ফাইল সি.পি.

def save_result(result):
    print('save the result')

save_resultথেকে পদ্ধতিটি সরিয়ে ফেলতে অনুমতি দেবে এবং এভাবে খ-এ থেকে এ এর ​​আমদানি সরিয়ে দেবে:

রিফ্যাক্টর ফাইল এপি

from b import B
from c import save_result

class A:
    @staticmethod
    def do_something_a_ish(param):
        A.save_result(A.use_param_like_a_would(param))

    @staticmethod
    def do_something_related_to_b(param):
        B.do_something_b_ish(param)

রিফ্যাক্টর ফাইল বি.পি.

from c import save_result

class B:
    @staticmethod
    def do_something_b_ish(param):
        save_result(B.use_param_like_b_would(param))

সংক্ষেপে, যদি আপনার কাছে একটি সরঞ্জাম থাকে (যেমন পাইলট বা পাইচার্ম) যা স্থির হতে পারে এমন পদ্ধতিগুলির প্রতিবেদন করে, কেবলমাত্র staticmethodতাদের উপর একটি ডিকোরেটর নিক্ষেপ করা সতর্কতাটি নিঃশব্দ করার সর্বোত্তম উপায় নাও হতে পারে। যদিও পদ্ধতিটি ক্লাসের সাথে সম্পর্কিত বলে মনে হচ্ছে তবুও এটি আলাদা করা ভাল হতে পারে, বিশেষত যদি আপনার বেশ কয়েকটি ঘনিষ্ঠভাবে সম্পর্কিত মডিউল থাকে যা একই কার্যকারিতাটির প্রয়োজন হতে পারে এবং আপনি DRY নীতিগুলি অনুশীলন করতে চান।


2

বিজ্ঞপ্তি আমদানি বিভ্রান্ত হতে পারে কারণ আমদানি দুটি কাজ করে:

  1. এটি আমদানি করা মডিউল কোড কার্যকর করে
  2. আমদানি করা মডিউলটি বিশ্বব্যাপী প্রতীক টেবিল আমদানিতে যুক্ত করে

পূর্ববর্তীটি একবারে সম্পন্ন করা হয়, তবে প্রতিটি আমদানির বিবৃতিতে পরবর্তীটি। সার্কুলার আমদানি পরিস্থিতি তৈরি করে যখন আমদানি করা মডিউল আংশিক সম্পাদিত কোড সহ আমদানিকৃত ব্যবহার করে। ফলস্বরূপ এটি আমদানির বিবৃতি দেওয়ার পরে তৈরি বস্তুগুলি দেখতে পাবে না। কোডের নমুনার নীচে এটি দেখায়।

সার্কুলার আমদানিগুলি সর্বদাই এড়ানো চূড়ান্ত মন্দ নয়। ফ্লাস্কের মতো কিছু ফ্রেমওয়ার্কগুলিতে এগুলি বেশ প্রাকৃতিক এবং আপনার কোডগুলি মুছে ফেলার জন্য তাদের কোডকে কোডিং আরও ভাল করে না।

main.py

print 'import b'
import b
print 'a in globals() {}'.format('a' in globals())
print 'import a'
import a
print 'a in globals() {}'.format('a' in globals())
if __name__ == '__main__':
    print 'imports done'
    print 'b has y {}, a is b.a {}'.format(hasattr(b, 'y'), a is b.a)

b.by

print "b in, __name__ = {}".format(__name__)
x = 3
print 'b imports a'
import a
y = 5
print "b out"

a.py

print 'a in, __name__ = {}'.format(__name__)
print 'a imports b'
import b
print 'b has x {}'.format(hasattr(b, 'x'))
print 'b has y {}'.format(hasattr(b, 'y'))
print "a out"

মন্তব্য সহ পাইথন main.py আউটপুট

import b
b in, __name__ = b    # b code execution started
b imports a
a in, __name__ = a    # a code execution started
a imports b           # b code execution is already in progress
b has x True
b has y False         # b defines y after a import,
a out
b out
a in globals() False  # import only adds a to main global symbol table 
import a
a in globals() True
imports done
b has y True, a is b.a True # all b objects are available

1

আমি নিম্নলিখিত উপায়ে সমস্যার সমাধান করেছি এবং এটি কোনও ত্রুটি ছাড়াই ভাল কাজ করে। দুটি ফাইল বিবেচনা করুন a.pyএবং b.py

আমি a.pyএটিতে যুক্ত করেছি এবং এটি কাজ করে।

if __name__ == "__main__":
        main ()

a.py:

import b
y = 2
def main():
    print ("a out")
    print (b.x)

if __name__ == "__main__":
    main ()

b.py:

import a
print ("b out")
x = 3 + a.y

আউটপুট আমি পাই

>>> b out 
>>> a out 
>>> 5

0

ঠিক আছে, আমি মনে করি আমার একটি দুর্দান্ত সমাধান আছে। ধরা যাক আপনার ফাইল aএবং ফাইল রয়েছে b। আপনি একটি আছে defবা classফাইলে bযে আপনার মডিউলে ব্যবহার করতে চান a, কিন্তু আপনি অন্য কিছু আছে, হয় একটি def, classঅথবা ফাইল থেকে পরিবর্তনশীল aযে আপনি আপনার সংজ্ঞা বা ফাইলে ক্লাসে প্রয়োজন b। আপনি যা করতে পারেন তা হ'ল ফাইলের নীচে, aফাংশন বা ফাইলটি ক্লাস করার পরে যা ফাইলের aজন্য প্রয়োজন b, তবে ফাংশন বা ক্লাসটি ফাইলের আগে কল করার আগে bআপনার ফাইলটি প্রয়োজনীয় a, import b তারপরে বলুন , এবং এখানে মূল অংশটি রয়েছে , সংজ্ঞা বা ফাইল ক্লাস সব bপ্রয়োজন যে defবা classফাইল থেকেa(আসুন এটি কল করুন CLASS), আপনি বলেfrom a import CLASS

এটি কাজ করে কারণ আপনি bপাইথন কোনও ফাইলের আমদানির বিবৃতি কার্যকর না করেই ফাইলটি আমদানি করতে পারেন bএবং এভাবে আপনি কোনও বৃত্তাকার আমদানি বাদ দেন ।

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

ফাইল করুন:

class A(object):

     def __init__(self, name):

         self.name = name

CLASS = A("me")

import b

go = B(6)

go.dostuff

ফাইল বি:

class B(object):

     def __init__(self, number):

         self.number = number

     def dostuff(self):

         from a import CLASS

         print "Hello " + CLASS.name + ", " + str(number) + " is an interesting number."

Voila।


from a import CLASSআসলে এপিপিতে সমস্ত কোড কার্যকর করা এড়িয়ে যায় না সত্যই এটি ঘটে: (1) a.py এর সমস্ত কোড একটি বিশেষ মডিউল "__main__" হিসাবে চালিত হয়। (২) এখন import b, b.py এ শীর্ষ স্তরের কোডটি রান হয়ে যায় (ক্লাস বি সংজ্ঞায়িত) এবং তারপরে "__main__" এ ফিরে আসা নিয়ন্ত্রণ করে। (3) "__main__" অবশেষে নিয়ন্ত্রণে চলে যায় go.dostuff()। (4) যখন ডাস্টফ () আসে import a, এটি আবার a.py তে সমস্ত কোড চালায় , এবার মডিউল "এ" হিসাবে; তারপরে এটি নতুন মডিউল "এ" থেকে CLASS অবজেক্টটি আমদানি করে। সুতরাং বাস্তবে, import aআপনি b.py. এ কোথাও ব্যবহার করলে এটি সমানভাবে কাজ করবে।
ম্যাথিয়াস ফ্রিপ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.