__Init__.py কি জন্য?


2333

কি __init__.pyএকটি পাইথন উৎস ডিরেক্টরির মধ্যে জন্য?


16
@ রব_ফেরোয়ান_এডিটস এবং এই স্ট্যাকওভারফ্লো থ্রেড 37139786 এর নীচে দেওয়া মন্তব্য অনুসারে , মনে হয় যে init .py আর পাইথন ৩.৩++ এর প্রয়োজন নেই।
জুন 711

উত্তর:


1452

এটি কোনও প্যাকেজের প্রয়োজনীয় অংশ হিসাবে ব্যবহৃত হত ( পুরানো, প্রাক -3.3 " নিয়মিত প্যাকেজ" , নতুন 3.3+ "নামস্থান প্যাকেজ" নয় ) "

এখানে ডকুমেন্টেশন।

পাইথন দুটি ধরণের প্যাকেজ, নিয়মিত প্যাকেজ এবং নেমস্পেস প্যাকেজ সংজ্ঞায়িত করে। নিয়মিত প্যাকেজগুলি হ'ল 3.তিহ্যবাহী প্যাকেজগুলি যেমন পাইথন ৩.২ এবং তার আগে ছিল। একটি নিয়মিত প্যাকেজ সাধারণত একটি __init__.pyফাইল ধারণকারী ডিরেক্টরি হিসাবে প্রয়োগ করা হয় । যখন একটি নিয়মিত প্যাকেজ আমদানি করা হয়, তখন এই __init__.pyফাইলটি স্পষ্টতই কার্যকর করা হয় এবং এটির দ্বারা নির্ধারিত অবজেক্টগুলি প্যাকেজটির নেমস্পেসের নামের সাথে আবদ্ধ থাকে। এই __init__.pyফাইলটিতে একই পাইথন কোড থাকতে পারে যা অন্য কোনও মডিউল থাকতে পারে এবং পাইথন এটি আমদানি করার সময় মডিউলে কিছু অতিরিক্ত বৈশিষ্ট্য যুক্ত করবে।

তবে কেবল লিঙ্কটি ক্লিক করুন, এটিতে একটি উদাহরণ, আরও তথ্য এবং নামস্পেস প্যাকেজগুলির বিবরণ রয়েছে, প্যাকেজগুলি ছাড়াই __init__.py


187
এর অর্থ কী: "মডিউল অনুসন্ধানের পথে পরে ঘটে যাওয়া বৈধ মডিউলগুলি অনিচ্ছাকৃতভাবে স্ট্রিংয়ের মতো ডিরেক্টরি সহ ডিরেক্টরিগুলি রোধ করতে এটি করা হয়"?
কার্ল জি

97
@ কার্লজি পাইথন নামের তালিকা সমাধানের জন্য ডিরেক্টরিগুলির তালিকা অনুসন্ধান করে, যেমন, বিবৃতি আমদানি করুন। যেহেতু এগুলি কোনও ডিরেক্টরি হতে পারে এবং নির্ধারিতগুলি শেষ ব্যবহারকারীর দ্বারা যুক্ত করা যায়, বিকাশকারীদের ডাইরেক্টরগুলির মধ্যে 'স্ট্রিং' এর মতো একটি বৈধ পাইথন মডিউল, যেমন একটি নাম ভাগ করে নেওয়ার জন্য ডিরেক্টরিগুলি নিয়ে চিন্তিত হতে হবে। এটিকে হ্রাস করতে, এটি ডিরেক্টরিগুলি উপেক্ষা করে যা _ _ init _ _.py নামে কোনও ফাইল ধারণ করে না, ফাঁকা থাকলেও।
টু-বিট অ্যালকেমিস্ট

186
@ কার্লজি এটি চেষ্টা করুন। 'ডেটটাইম' নামে একটি ডিরেক্টরি তৈরি করুন এবং এতে দুটি খালি ফাইল তৈরি করুন, init.py ফাইল (আন্ডারস্কোর সহ) এবং ডেটটাইম.পি। এখন একটি দোভাষী খুলুন, সিজ আমদানি করুন এবং ইস্যু করুন sys.path.insert(0, '/path/to/datetime'), আপনি যে ডিরেক্টরিটি তৈরি করেছেন কেবল সেই পথটির পরিবর্তে সেই পথটিকে প্রতিস্থাপন করুন। এখন কিছু চেষ্টা করুন from datetime import datetime;datetime.now()। আপনার একটি অ্যাট্রিবিউটআরার পাওয়া উচিত (কারণ এটি এখন আপনার ফাঁকা ফাইল আমদানি করছে)। যদি আপনি ফাঁকা init ফাইল তৈরি না করে এই পদক্ষেপগুলি পুনরাবৃত্তি করেন তবে এটি হবে না। এটি প্রতিরোধের উদ্দেশ্যে এটিই।
টু-বিট অ্যালকেমিস্ট

4
@ DarekNędza আপনি যদি একটি পাইথন দোভাষী এবং from datetime import datetimeত্রুটি ছাড়াই ইস্যু করতে না পারেন তবে আপনার কিছু ভুলভাবে সেট আপ হয়েছে । এটি ভার্সন ২.৩-এ ফিরে যাওয়ার মতো!
টু-বিট অ্যালকেমিস্ট

5
@ সোয়াং: এটি ভুল: builtinsঅন্তর্নির্মিত ফাংশন এবং ক্লাসগুলির তালিকা তৈরি করে , অন্তর্নির্মিত মডিউলগুলি নয় (সিএফ। ডকস.পিথন.আর.আর / টিউটোরিয়াল / মডেলস html#t- ডির- ফাংশন )। আপনি যদি অন্তর্নির্মিত মডিউলগুলি তালিকাবদ্ধ করতে চান তবে import sys; print(sys.builtin_module_names)(সিএফ। ডকস.পিথন.আর. / 3 / লাইব্রেরি / সিসিইচটিএমএল#sys.builtin_module_names ) করুন।
ম্যাগগিরো

842

নামের ফাইলগুলি __init__.pyডিস্কে ডিরেক্টরিগুলি পাইথন প্যাকেজ ডিরেক্টরি হিসাবে চিহ্নিত করতে ব্যবহৃত হয়। আপনার যদি ফাইল থাকে

mydir/spam/__init__.py
mydir/spam/module.py

এবং mydirআপনার পথে, আপনি কোড module.pyহিসাবে আমদানি করতে পারেন

import spam.module

অথবা

from spam import module

আপনি যদি __init__.pyফাইলটি সরিয়ে ফেলেন , পাইথন আর সেই ডিরেক্টরিতে সাবমোডিয়ুলগুলির সন্ধান করবে না, সুতরাং মডিউলটি আমদানির প্রচেষ্টা ব্যর্থ হবে।

__init__.pyফাইল সাধারণত খালি থাকে, কিন্তু আরও বেশি সুবিধাজনক নাম, হোল্ড সুবিধা ফাংশন, ইত্যাদি উদাহরণস্বরূপ দেওয়া উপরোক্ত অধীনে প্যাকেজের নির্বাচিত অংশ রপ্তানি করতে ব্যবহার করা যেতে পারে, Init মডিউল বিষয়বস্তু যেমন অ্যাক্সেস করা যেতে পারে

import spam

উপর ভিত্তি করে এই


96
আপডেট: ফাইলটি __init__.pyপাইথন ২ এক্স এর অধীনে প্রয়োজনীয় ছিল এবং এটি পাইথন ২.7.১২ এর অধীনে আবশ্যক (আমি এটি পরীক্ষা করেছি) তবে পাইথন ৩.৩ এর পরে এটি আর প্রয়োজন নেই (পাইথন ৩.৪.৩ এর অধীনে (I) এটি পরীক্ষিত)। আরও তথ্যের জন্য stackoverflow.com/questions/37139786 দেখুন ।
রব_ফরফ_এডিটস

4
এটি ব্যবহার করবেন না। এটি "নেমস্পেস" প্যাকেজ, কোনও নিয়মিত প্যাকেজ নয়। নেমস্পেস প্যাকেজটি খুব বিরল ব্যবহারের ক্ষেত্রে ব্যবহৃত হয়। এটি কখন ব্যবহার করবেন তা আপনার জানা দরকার নেই। শুধু ব্যবহার __init__.py
মিথেন

2
তবে আপনার যদি থাকে setup.pyএবং আপনি find_packages()এটি ব্যবহার করেন তবে __init__.pyপ্রতিটি ডিরেক্টরিতে এটি প্রয়োজনীয় । দেখুন stackoverflow.com/a/56277323/7127824
techkuz

483

একটি পাইথন প্যাকেজ হিসাবে একটি ডিরেক্টরি লেবেল এবং সংজ্ঞা ছাড়াও __all__, __init__.pyআপনি প্যাকেজ পর্যায়ে কোনো পরিবর্তনশীল নির্ধারণ করতে দেয়। কোনও প্যাকেজ কোনও এপিআই-জাতীয় ফ্যাশনে ঘন ঘন আমদানি করা এমন কোনও সংজ্ঞা নির্ধারণ করে তবে এটি করা প্রায়শই সুবিধাজনক। এই প্যাটার্নটি পাইথোনিক "ফ্ল্যাট নেস্টেডের চেয়ে ভাল" দর্শনের আনুগত্যকে উত্সাহ দেয়।

একটি উদাহরণ

এখানে আমার প্রকল্প, যা আমি প্রায়শই আমদানি একটি এক থেকে একটি উদাহরণ sessionmakerবলা Sessionআমার ডাটাবেসের সাথে যোগাযোগ করার জন্য। আমি কয়েকটি মডিউল সহ একটি "ডাটাবেস" প্যাকেজ লিখেছি:

database/
    __init__.py
    schema.py
    insertions.py
    queries.py

আমার __init__.pyমধ্যে নিম্নলিখিত কোড রয়েছে:

import os

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)

যেহেতু আমি Sessionএখানে সংজ্ঞা দিচ্ছি , আমি নীচের বাক্য গঠন ব্যবহার করে একটি নতুন সেশন শুরু করতে পারি। এই কোডটি "ডাটাবেস" প্যাকেজ ডিরেক্টরিটির ভিতরে বা বাইরে থেকে একই রকম কার্যকর হবে।

from database import Session
session = Session()

অবশ্যই এটি একটি ছোট সুবিধা - বিকল্পটি Sessionআমার ডাটাবেস প্যাকেজে "create_session.py" এর মতো একটি নতুন ফাইলে সংজ্ঞায়িত করা এবং এটি ব্যবহার করে নতুন সেশন শুরু করতে হবে:

from database.create_session import Session
session = Session()

আরও পড়া

এখানে যথাযথ ব্যবহারগুলি জুড়ে একটি চমত্কার আকর্ষণীয় reddit থ্রেড রয়েছে __init__.py:

http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/

সংখ্যাগরিষ্ঠ মতামতটি মনে হয় যে __init__.py"স্পষ্টকৃতর চেয়ে ভাল ভাল" দর্শনের লঙ্ঘন এড়াতে ফাইলগুলি খুব পাতলা হওয়া উচিত।


3
engine, sessionmaker, create_engine, এবং osসব থেকে আমদানি করা যেতে পারে databaseএখন ... দেখে মনে হচ্ছে আপনি যে নামস্থান একটি জগাখিচুড়ি তৈরি করেছি।
আর্টঅফ ওয়ারফেয়ার

9
@ আর্টঅফ ওয়ারফেয়ার, আপনি __all__ = [...]যা দিয়ে আমদানি করা হয়েছে তা সীমাবদ্ধ করতে ব্যবহার করতে পারেন import *। তবে এটি থেকে আলাদা, হ্যাঁ, আপনি একটি অগোছালো শীর্ষ-স্তরের নেমস্পেস রেখে গেছেন।
নাথান গোল্ড

আমি কি জানতে পারি 'ডেটাবাস ইউআরএল' কী? আমি 'mysql + mysqldb: // রুট: পাইথন @ লোকালহোস্ট: 3306 / পরীক্ষা' দিয়ে ক্রিয়েট_ইঙ্গিনটি বন্ধ করে এটির প্রতিলিপি দেওয়ার চেষ্টা করেছি তবে এটি কার্যকর হয় না। ধন্যবাদ।
সানিবোইজ

1
আপনি কিভাবে এক্সেস 'সেশন' বর্গ সংজ্ঞায়িত হবে Init ভিতরে ভিতরে প্যাকেজ যেমন quieries.py থেকে?
vldbnc

252

এর জন্য প্রধান দুটি কারণ রয়েছে __init__.py

  1. সুবিধার জন্য: অন্যান্য ব্যবহারকারীদের আপনার প্যাকেজ শ্রেণিবিন্যাসে আপনার ফাংশনগুলির সঠিক অবস্থান জানতে হবে না।

    your_package/
      __init__.py
      file1.py
      file2.py
        ...
      fileN.py
    # in __init__.py
    from file1 import *
    from file2 import *
    ...
    from fileN import *
    # in file1.py
    def add():
        pass

    তারপরে অন্যরা অ্যাড () এ কল করতে পারে

    from your_package import add

    ফাইল 1 না জেনে যেমন

    from your_package.file1 import add
  2. আপনি যদি কিছু শুরু করতে চান; উদাহরণস্বরূপ, লগিং (যা শীর্ষ স্তরে স্থাপন করা উচিত):

    import logging.config
    logging.config.dictConfig(Your_logging_config)

6
ওহ, আপনার উত্তরটি পড়ার আগে আমি ভেবেছিলাম কোনও ফাংশনটির অবস্থান থেকে এটি স্পষ্টভাবে কল করা একটি ভাল অনুশীলন।
অ্যারিন

2
@ অ্যারিনের পক্ষে সংক্ষিপ্ত বিবৃতিগুলি (বা এই ক্ষেত্রে, বিষয়গত সিদ্ধান্ত) সর্বদা সত্য বলে বিবেচনা না করা ভাল। থেকে আমদানি __init__.pyকরা কখনও কখনও দরকারী হতে পারে, কিন্তু সর্বদা না।
টোবিয়াস সেটেট

2
এই কোডগুলি আমদানির সময় বা রানটাইমে কার্যকর করা হয়?
ব্যবহারকারী 1559897

111

__init__.pyফাইল পাইথন আচরণ মডিউল যেমন ধারণকারী ডিরেক্টরি করে তোলে।

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


89

পাইথন ৩.৩ থেকে যেহেতু __init__.pyআর ডিরেক্টরিগুলি আমদানিযোগ্য পাইথন প্যাকেজ হিসাবে সংজ্ঞায়িত করার প্রয়োজন হয় না।

পিইপি 420 পরীক্ষা করুন : অন্তর্ভুক্ত নেমস্পেস প্যাকেজগুলি :

প্যাকেজ ডিরেক্টরিগুলির জন্য স্থানীয় সমর্থন যা __init__.pyমার্কার ফাইলের প্রয়োজন হয় না এবং স্বয়ংক্রিয়ভাবে একাধিক পাথ খণ্ড বিস্তৃত করতে পারে ( পিইপি 420 তে বর্ণিত হিসাবে নেমস্পেস প্যাকেজগুলির বিভিন্ন তৃতীয় পক্ষের পদ্ধতির দ্বারা অনুপ্রাণিত )

পরীক্ষাটি এখানে:

$ mkdir -p /tmp/test_init
$ touch /tmp/test_init/module.py /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
├── module.py
└── __init__.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

$ rm -f /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
└── module.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

তথ্যসূত্র:
https://docs.python.org/3/whatsnew/3.3.html#pep-420-imp ণী-namespace-packages
https://www.python.org/dev/peps/pep-0420/
হয় __init__। পাইথন 3 এ প্যাকেজগুলির জন্য পিআই প্রয়োজন হয় না?


3
এটি "নেমস্পেস" প্যাকেজ। এটি নিয়মিত প্যাকেজের জন্য ব্যবহার করবেন না।
মিথেন

@ মিতান, আপনি কি আপনার মন্তব্যে বিস্তারিত বলতে পারবেন?
রবার্ট লগ


57

পাইথনে প্যাকেজের সংজ্ঞাটি খুব সহজ। জাভা এর মতো হায়ারারিকাল স্ট্রাকচার এবং ডিরেক্টরি স্ট্রাকচার একই রকম। তবে আপনার __init__.pyএকটি প্যাকেজ থাকতে হবে। আমি __init__.pyনীচের উদাহরণ দিয়ে ফাইলটি ব্যাখ্যা করব :

package_x/
|--  __init__.py
|--    subPackage_a/
|------  __init__.py
|------  module_m1.py
|--    subPackage_b/
|------  __init__.py
|------  module_n1.py
|------  module_n2.py
|------  module_n3.py

__init__.pyযতক্ষণ না এটি খালি থাকতে পারে। এটি নির্দেশ করে যে ডিরেক্টরিটিকে প্যাকেজ হিসাবে বিবেচনা করা উচিত। অবশ্যই, __init__.pyউপযুক্ত সামগ্রী সেট করতে পারেন।

আমরা যদি মডিউল_এন 1 এ কোনও ফাংশন যুক্ত করি:

def function_X():
    print "function_X in module_n1"
    return

দৌড়ানোর পরে:

>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()

function_X in module_n1 

তারপরে আমরা হায়ারার্কি প্যাকেজটি অনুসরণ করেছি এবং মডিউল_এন 1টিকে ফাংশন বলে। আমরা __init__.pyউপ-প্যাকেজ_বিতে এটি ব্যবহার করতে পারি :

__all__ = ['module_n2', 'module_n3']

দৌড়ানোর পরে:

>>>from package_x.subPackage_b import * 
>>>module_n1.function_X()

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named module_n1

সুতরাং * আমদানি করে মডিউল প্যাকেজটি __init__.pyবিষয়বস্তু সাপেক্ষে ।


আমার সেটআপ.পি প্যাকেজযুক্ত লাইব্রেরির মাধ্যমে কীভাবে একই আমদানি করতে দেখবে? from package_x.subPackage_b.module_n1 import function_X
টেকনাজি

তাই কী নিতে দূরে এখানে হয় "ব্যবহার * আমদানি, মডিউল প্যাকেজ বিষয় হল init .py বিষয়বস্তু"
মিনি শি

54

যদিও পাইথন কোনও __init__.pyফাইল ছাড়াই কাজ করে তবে আপনার একটি ফাইল অন্তর্ভুক্ত করা উচিত।

এটি নির্দিষ্ট করে যে কোনও প্যাকেজটিকে মডিউল হিসাবে বিবেচনা করা উচিত, সুতরাং এটি অন্তর্ভুক্ত করুন (এমনকি এটি খালি থাকলেও)।

এমন একটি ক্ষেত্রে রয়েছে যেখানে আপনি আসলে কোনও __init__.pyফাইল ব্যবহার করতে পারেন :

আপনার নিম্নলিখিত ফাইলের কাঠামোটি কল্পনা করুন:

main_methods 
    |- methods.py

এবং এটি methods.pyরয়েছে:

def foo():
    return 'foo'

ব্যবহার foo()করতে আপনার নিম্নলিখিতগুলির একটি প্রয়োজন:

from main_methods.methods import foo # Call with foo()
from main_methods import methods # Call with methods.foo()
import main_methods.methods # Call with main_methods.methods.foo()

হয়তো আপনি প্রয়োজন (অথবা চান) রাখার methods.pyভিতরে main_methods(উদাহরণস্বরূপ রানটাইম / নির্ভরতা) কিন্তু আপনি শুধুমাত্র আমদানি করতে চান main_methods


আপনি নাম পরিবর্তন যদি methods.pyকরতে __init__.pyতাহলে আপনি ব্যবহার করতে পারে foo()মাত্র আমদানি করে main_methods:

import main_methods
print(main_methods.foo()) # Prints 'foo'

এটি কাজ করে কারণ __init__.pyপ্যাকেজের অংশ হিসাবে বিবেচিত হয়।


কিছু পাইথন প্যাকেজ আসলে এটি করে। একটি উদাহরণ জেএসএনের সাথে রয়েছে , যেখানে দৌড়ানো import jsonআসলে প্যাকেজ __init__.pyথেকে আমদানি করে json( প্যাকেজ ফাইলের কাঠামো এখানে দেখুন ):

সোর্স কোড: Lib/json/__init__.py


39

__init__.py এটি লোডযোগ্য মডিউল হিসাবে থাকা ডিরেক্টরিটিকে চিকিত্সা করবে।

যারা কোড পড়ার পক্ষে পছন্দ করেন তাদের জন্য আমি এখানে দ্বি-বিট আলকেমিস্টের মন্তব্য রেখেছি ।

$ find /tmp/mydir/
/tmp/mydir/
/tmp/mydir//spam
/tmp/mydir//spam/__init__.py
/tmp/mydir//spam/module.py
$ cd ~
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
>>> module.myfun(3)
9
>>> exit()
$ 
$ rm /tmp/mydir/spam/__init__.py*
$ 
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named spam
>>> 

30

এটি অন্যান্য অজগর ফাইল আমদানি করতে সহায়তা করে। আপনি যখন এই ফাইলটি অন্য পাই ফাইল যুক্ত ডিরেক্টরিতে (স্টাফ বলুন) রাখেন, তখন আপনি আমদানি স্টাফ-এর মতো কিছু করতে পারেন।

root\
    stuff\
         other.py

    morestuff\
         another.py

__init__.pyডিরেক্টরি স্টাফের ভিতরে এটি ব্যতীত আপনি অন্য.py আমদানি করতে পারবেন না, কারণ পাইথন জানেন না স্টাফের উত্স কোডটি কোথায় এবং এটি প্যাকেজ হিসাবে স্বীকৃতি দিতে অক্ষম।


2
আমার প্রকল্পে আমার একই কাঠামো রয়েছে (পাইথন ৩.৪) তবে আমি অন্য.পি দেখতে অন্য.পি দেখতে সক্ষম নই। আমি কীভাবে আমদানি করব? রুট.স্টফ থেকে অন্য আমদানি করবেন? এটি ভিএসকোড ডিবাগ মোডে কাজ করে তবে কমান্ড লাইনে নয়। কোন ধারনা?
রডরিগর্ফ 23:58

10

একটি __init__.pyফাইল আমদানি সহজ করে তোলে। যখন কোনও __init__.pyপ্যাকেজের মধ্যে উপস্থিত থাকে, তখন ফাংশনটি এই জাতীয় a()ফাইল থেকে আমদানি করা b.pyযায়:

from b import a

এটি ছাড়া, আপনি সরাসরি আমদানি করতে পারবেন না। আপনাকে সিস্টেমের পথে সংশোধন করতে হবে:

import sys
sys.path.insert(0, 'path/to/b.py')

from b import a

আপনার অর্থ " ফাংশন এ () ফাইল বি.পি. [স্নিপেট] থেকে আমদানি করা যায়, তবে আপনি সরাসরি আমদানি করতে পারবেন না ?" আমি __init__.py ছাড়াই b.py ফাইল থেকে a () ফাংশনটি আমদানি করতে পারি।
অ্যাডারচক্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.