পাইথনে কেউ __ সমস্ত__ কি ব্যাখ্যা করতে পারে?


982

আমি পাইথনকে আরও বেশি করে ব্যবহার করছি এবং আমি __all__বিভিন্ন __init__.pyফাইলে ভেরিয়েবল সেটটি দেখতে থাকি । কেউ কি এটি ব্যাখ্যা করতে পারে?

উত্তর:


565

এটি সেই মডিউলটির পাবলিক অবজেক্টের একটি তালিকা, যার দ্বারা ব্যাখ্যা করা হয়েছে import *। এটি আন্ডারস্কোর দিয়ে শুরু হওয়া সমস্ত কিছু লুকানোর ডিফল্টকে ওভাররাইড করে।


146
আন্ডারস্কোর দিয়ে শুরু হওয়া বা উপস্থিত __all__থাকলে উল্লেখ না করা অবজেক্টগুলি __all__ঠিক লুকানো নয়; আপনি যদি তাদের নামগুলি জানেন তবে এগুলি যথাযথভাবে দেখা যায় এবং অ্যাক্সেস করা যায়। এটি কেবলমাত্র "আমদানি *" এর ক্ষেত্রে, যা কোনওভাবেই সুপারিশ করা হয় না, পার্থক্যটি কোনও ওজন বহন করে।
ব্র্যান্ডন রোডস

28
@ ব্র্যান্ডন রোডস: এটিও ঠিক সত্য নয়: এটি কেবলমাত্র এমন মডিউলগুলি আমদানি করার পরামর্শ দেওয়া হয় যা আপনি ডিজাইন করেছেন import *(যেমন যেমন tk)। একটি ভাল ইঙ্গিত যদি এটি হয় __all__তবে মডিউলের কোডটিতে আন্ডারস্কোর দিয়ে শুরু হওয়া উপস্থিতি বা নামগুলি।
উড়ন্ত ভেড়া

12
সার্বজনীন এবং অভ্যন্তরীণ ইন্টারফেস - পাইথন.আর / দেবদেবী / পেপস / পেপ-0008/ # id50 , অন্তর্নির্ধারণের আরও ভাল সমর্থন করার জন্য মডিউলগুলিকে __all__ বৈশিষ্ট্যটি ব্যবহার করে তাদের সর্বজনীন API এ স্পষ্টভাবে নামগুলি প্রকাশ করা উচিত। __All__ কে খালি তালিকায় সেট করা ইঙ্গিত দেয় যে মডিউলটির সর্বজনীন এপিআই নেই।
ডিবাগ করুন

আমি নিশ্চিত না যে যদি tkআজ (বা ২০১২, এমনকি) মুক্তি দেওয়া হয় তবে প্রস্তাবিত অনুশীলনটি ব্যবহার করা হবে from tk import *। আমি মনে করি অনুশীলন জড়তার কারণে গ্রহণ করা হয়েছে, ইচ্ছাকৃত ডিজাইনের কারণে নয়।
চ্যানার

ব্র্যান্ডন রোডস যেমন উল্লেখ করেছে এটি সত্যই সঠিক নয়
দু'ইম

946

লিঙ্কযুক্ত, তবে এখানে স্পষ্টভাবে উল্লেখ করা হয়নি, কখন __all__ব্যবহৃত হয়। এটি মডিউলটিতে from <module> import *ব্যবহৃত হলে কোন মডিউলটি রফতানি হবে তা নির্ধারণ করে এমন স্ট্রিংয়ের একটি তালিকা ।

উদাহরণস্বরূপ, নিম্নলিখিত কোডটি foo.pyস্পষ্টভাবে প্রতীকগুলি রফতানি করে barএবং baz:

__all__ = ['bar', 'baz']

waz = 5
bar = 10
def baz(): return 'baz'

এই চিহ্নগুলি এর পরেও আমদানি করা যায়:

from foo import *

print(bar)
print(baz)

# The following will trigger an exception, as "waz" is not exported by the module
print(waz)

তাহলে __all__উপরে মন্তব্য করা হয়, এই কোড তারপর, সমাপ্তির চালানো হবে ডিফল্ট ব্যবহারকে import *সব প্রতীক যা একটি আন্ডারস্কোর দিয়ে শুরু করবেন না, দেওয়া নামস্থান থেকে আমদানি করা হয়।

তথ্যসূত্র: https://docs.python.org/tutorial/modules.html#importing-from-a- প্যাকেজ

বিঃদ্রঃ: __all__from <module> import * কেবল আচরণকেই প্রভাবিত করে । যে সদস্যদের উল্লেখ করা __all__হয়নি তারা মডিউলের বাইরে থেকে অ্যাক্সেসযোগ্য এবং এর সাথে আমদানি করা যায় from <module> import <member>


1
আমাদের কি বাজ ছাপানো উচিত নয় print(baz())?
জন কোল

@ জনকোল বাজ হ'ল ফাংশন অবজেক্ট এবং বাজ () ফাংশন অবজেক্টটি পরিচালনা করবেন
ভানু তেজ

@ ভানুটিজ হুবহু তাই print(baz)ভালো কিছু ছাপে <function baz at 0x7f32bc363c10>যেহেতু print(baz())কপি করে প্রিন্টbaz
জন কোল

223

পাইথনে __ সমস্ত__ ব্যাখ্যা কর?

আমি __all__বিভিন্ন __init__.pyফাইলে ভেরিয়েবল সেটটি দেখতে থাকি ।

এটি কি করে?

কি করে __all__?

এটি মডিউল থেকে শব্দার্থগতভাবে "সর্বজনীন" নাম ঘোষণা করে। যদি কোনও নাম থাকে তবে __all__ব্যবহারকারীরা এটি ব্যবহার করবেন বলে আশা করা হচ্ছে এবং এটি পরিবর্তিত হবে না এমন প্রত্যাশা তাদের থাকতে পারে।

এটি প্রোগ্রামিয়াত প্রভাব ফেলবে:

import *

__all__একটি মডিউল, যেমন module.py:

__all__ = ['foo', 'Bar']

এর অর্থ হ'ল আপনি যখন import *মডিউলটি থেকে, কেবলমাত্র সেই নামগুলি __all__আমদানি করা হয়:

from module import *               # imports foo and Bar

ডকুমেন্টেশন সরঞ্জাম

ডকুমেন্টেশন এবং কোড স্বতঃপূরণ সরঞ্জামগুলি (প্রকৃতপক্ষে, উচিত) __all__মডিউল থেকে কী নামগুলি প্রদর্শিত হবে তা নির্ধারণ করতেও পরীক্ষা করতে পারে।

__init__.py ডিরেক্টরিটি পাইথন প্যাকেজ তৈরি করে

ডক্স থেকে :

__init__.pyফাইল পাইথন আচরণ যেমন প্যাকেজ ধারণকারী ডিরেক্টরি তৈরি করতে প্রয়োজন বোধ করা হয়; স্ট্রিংয়ের মতো একটি সাধারণ নাম সহ ডিরেক্টরিগুলি অনিচ্ছাকৃতভাবে মডিউল অনুসন্ধানের পথে পরে আসা বৈধ মডিউলগুলি আড়াল করা থেকে করা যায়।

সবচেয়ে সহজ ক্ষেত্রে, __init__.pyখালি ফাইল হতে পারে তবে এটি প্যাকেজের জন্য আরম্ভকরণ কোডটি কার্যকর করতে পারে বা __all__ভেরিয়েবল সেট করতে পারে।

সুতরাং একটি প্যাকেজ জন্য __init__.pyঘোষণা করতে পারেন ।__all__

একটি এপিআই পরিচালনা করা:

একটি প্যাকেজ সাধারণত মডিউলগুলি নিয়ে তৈরি হয় যা একে অপরকে আমদানি করতে পারে তবে এটি অবশ্যই একটি __init__.pyফাইলের সাথে আবদ্ধ । সেই ফাইলটিই ডিরেক্টরিটি একটি বাস্তব পাইথন প্যাকেজ তৈরি করে। উদাহরণস্বরূপ, বলুন আপনার একটি প্যাকেজে নিম্নলিখিত ফাইল রয়েছে:

package
├── __init__.py
├── module_1.py
└── module_2.py

পাইথন দিয়ে এই ফাইলগুলি তৈরি করুন যাতে আপনি পাশাপাশি অনুসরণ করতে পারেন - আপনি নিম্নলিখিতটি একটি পাইথন 3 শেলের মধ্যে পেস্ট করতে পারেন:

from pathlib import Path

package = Path('package')
package.mkdir()

(package / '__init__.py').write_text("""
from .module_1 import *
from .module_2 import *
""")

package_module_1 = package / 'module_1.py'
package_module_1.write_text("""
__all__ = ['foo']
imp_detail1 = imp_detail2 = imp_detail3 = None
def foo(): pass
""")

package_module_2 = package / 'module_2.py'
package_module_2.write_text("""
__all__ = ['Bar']
imp_detail1 = imp_detail2 = imp_detail3 = None
class Bar: pass
""")

এবং এখন আপনি একটি সম্পূর্ণ এপিআই উপস্থাপন করেছেন যা অন্য কেউ যখন আপনার প্যাকেজটি আমদানি করেন তখন তারা ব্যবহার করতে পারে:

import package
package.foo()
package.Bar()

এবং প্যাকেজটিতে packageনেমস্পেসের বিশৃঙ্খলা সৃষ্টি করে আপনার মডিউলগুলি তৈরি করার সময় আপনি ব্যবহার করেছেন এমন সমস্ত অন্যান্য প্রয়োগের বিশদ থাকবে না ।

__all__ ভিতরে __init__.py

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

package
├── __init__.py
├── module_1
│   ├── foo_implementation.py
│   └── __init__.py
└── module_2
    ├── Bar_implementation.py
    └── __init__.py

প্রথমে মডিউলগুলির মতো একই নাম সহ সাব-প্যাকেজ ডিরেক্টরিগুলি তৈরি করুন:

subpackage_1 = package / 'module_1'
subpackage_1.mkdir()
subpackage_2 = package / 'module_2'
subpackage_2.mkdir()

বাস্তবায়নগুলি সরান:

package_module_1.rename(subpackage_1 / 'foo_implementation.py')
package_module_2.rename(subpackage_2 / 'Bar_implementation.py')

__init__.pyউপ-প্যাকেজগুলির জন্য এস তৈরি করুন __all__যা প্রতিটিটির জন্য ঘোষণা করে :

(subpackage_1 / '__init__.py').write_text("""
from .foo_implementation import *
__all__ = ['foo']
""")
(subpackage_2 / '__init__.py').write_text("""
from .Bar_implementation import *
__all__ = ['Bar']
""")

এবং এখন আপনার প্যাকেজ স্তরে এপিআই সরবরাহ করা আছে:

>>> import package
>>> package.foo()
>>> package.Bar()
<package.module_2.Bar_implementation.Bar object at 0x7f0c2349d210>

এবং আপনি সহজেই আপনার API এ জিনিসগুলি যুক্ত করতে পারেন যা আপনি সাবপ্যাকেজের মডিউল স্তরের পরিবর্তে সাবপ্যাকেজ স্তরে পরিচালনা করতে পারেন can আপনি যদি __init__.pyএপিআইতে একটি নতুন নাম যুক্ত করতে চান তবে আপনি কেবল আপডেট করুন , উদাহরণস্বরূপ মডিউল ৩:

from .Bar_implementation import *
from .Baz_implementation import *
__all__ = ['Bar', 'Baz']

এবং আপনি যদি Bazশীর্ষ স্তরের এপিআইতে প্রকাশ করতে প্রস্তুত না হন তবে আপনার শীর্ষ স্তরে __init__.pyআপনার থাকতে পারে:

from .module_1 import *       # also constrained by __all__'s
from .module_2 import *       # in the __init__.py's
__all__ = ['foo', 'Bar']     # further constraining the names advertised

এবং যদি আপনার ব্যবহারকারীগণের প্রাপ্যতা সম্পর্কে সচেতন হন তবে Bazতারা এটি ব্যবহার করতে পারেন:

import package
package.Baz()

তবে তারা যদি এটি সম্পর্কে না জানে তবে অন্যান্য সরঞ্জামগুলি ( পাইডোকের মতো ) তাদের জানাবে না।

আপনি পরে পরিবর্তন করতে পারেন যখন Bazপ্রাইম টাইমের জন্য প্রস্তুত থাকে:

from .module_1 import *
from .module_2 import *
__all__ = ['foo', 'Bar', 'Baz']

Prefixing _বনাম __all__:

ডিফল্টরূপে পাইথন এমন সমস্ত নাম রফতানি করবে যা একটি দিয়ে শুরু হয় না _। আপনি অবশ্যই এই প্রক্রিয়া উপর নির্ভর করতে পারে । পাইথন মান গ্রন্থাগার মধ্যে কিছু প্যাকেজ, আসলে, না এই উপর নির্ভর, কিন্তু তাই উদাহরণস্বরূপ তাদের আমদানির ওরফে তারা কি করতে, ctypes/__init__.py:

import os as _os, sys as _sys

_কনভেনশনটি ব্যবহার করা আরও মার্জিত হতে পারে কারণ এটি আবার নামকরণের অপ্রয়োজনীয়তা সরিয়ে দেয়। তবে এটি আমদানির জন্য অপ্রয়োজনীয় যোগ করে (যদি আপনার প্রচুর পরিমাণ থাকে) এবং এটি ধারাবাহিকভাবে করা ভুলে যাওয়া সহজ - এবং আপনি যে সর্বশেষ জিনিসটি চান তা হ'ল অনির্দিষ্টকালের জন্য এমন কিছু সমর্থন করা যা আপনি কেবল একটি বাস্তবায়নের বিশদ হতে চান, কেবল কারণ আপনি উপসর্গ করতে ভুলে গেছেন_ কোনও ফাংশনটির নামকরণের সময় একটি ।

আমি ব্যক্তিগতভাবে একটি লিখুন __all__ মডিউলগুলির জন্য আমার বিকাশের জীবনচক্রটি প্রথম দিকে যাতে অন্যরা যারা আমার কোড ব্যবহার করতে পারে তাদের কী ব্যবহার করা উচিত এবং কী ব্যবহার করা উচিত তা জানতে পারে।

স্ট্যান্ডার্ড লাইব্রেরির বেশিরভাগ প্যাকেজগুলিও ব্যবহার করে __all__

এড়ানো যখন __all__ বোঝা যায়

_এর বদলে উপসর্গের সম্মেলনে লেগে থাকা অর্থপূর্ণ sense__all__ :

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

একটি exportসাজসজ্জা

ব্যবহারের খারাপ দিকটি __all__হ'ল আপনাকে দুটি বার রফতানি করা ফাংশন এবং ক্লাসগুলির নাম লিখতে হবে - এবং সংজ্ঞাগুলি থেকে তথ্য আলাদা রাখা হয়। আমরা এই সমস্যাটি সমাধান করার জন্য একটি ডেকরেটার ব্যবহার করতে পারি

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

সুতরাং, উদাহরণস্বরূপ, একটি ইউটিলিটি লাইব্রেরি, আপনি সাজসজ্জারকে সংজ্ঞায়িত করবেন:

import sys

def export(fn):
    mod = sys.modules[fn.__module__]
    if hasattr(mod, '__all__'):
        mod.__all__.append(fn.__name__)
    else:
        mod.__all__ = [fn.__name__]
    return fn

এবং তারপরে, যেখানে আপনি একটি সংজ্ঞা দেবেন __all__, আপনি এটি করুন:

$ cat > main.py
from lib import export
__all__ = [] # optional - we create a list if __all__ is not there.

@export
def foo(): pass

@export
def bar():
    'bar'

def main():
    print('main')

if __name__ == '__main__':
    main()

এবং এটি মূল হিসাবে চালিত হয় বা অন্য কোনও ফাংশন দ্বারা আমদানি করা সূক্ষ্মভাবে কাজ করে।

$ cat > run.py
import main
main.main()

$ python run.py
main

এবং এপিআই প্রভিশনগুলিও কার্যকর import *হবে:

$ cat > run.py
from main import *
foo()
bar()
main() # expected to error here, not exported

$ python run.py
Traceback (most recent call last):
  File "run.py", line 4, in <module>
    main() # expected to error here, not exported
NameError: name 'main' is not defined

1
ক্রস রেফারেন্স: আমি কীভাবে ডেকোরেটর লিখতে হয় সেই প্রশ্নের উত্তরটি এই সিডব্লিউটিতে আপনার ডেকরেটারের উল্লেখ করেছি @export
এমভিজি

13
তুলনামূলকভাবে নতুন পাইথন বিকাশকারীকে মডিউল / প্যাকেজগুলি আমদানি করার প্রক্রিয়া __init__.pyএবং এর ব্যবহার সম্পর্কে বুঝতে সাহায্য করার ক্ষেত্রে আমি এটিই সবচেয়ে সহায়ক উত্তর পেয়েছি__all__
ব্রেট রেইনহার্ড

এটি আমাকে অনেক সাহায্য করে। আমার সমস্যাটি হ'ল, আমি যে সাব-মডিউলগুলি আমদানি করতে চাইছি সেগুলি __all__হ'ল ম্যানুয়ালি এটি সঠিক কিনা তা নিশ্চিত না করে তাদের প্রতীকগুলিতে প্রচুর ক্রাফ্টযুক্ত সমস্ত উত্পন্ন ফাইল ।
মাইক সি

@ মাইকিসি তখন আপনার __all__নিজেরও উত্পন্ন করা উচিত - তবে আমি বলব আপনার একটি অস্থির এপিআই রয়েছে ... এটির জন্য কিছু ব্যাপক গ্রহণযোগ্যতা পরীক্ষা হবে have
অ্যারন হল

"তারা সব অন্যান্য নামগুলি থাকবে না ... প্যাকেজ নামস্থান আপ cluttering" @AaronHall কিন্তু তারা হবে নাম আছে module_1এবং module_2; এটা একটি সুনির্দিষ্ট অন্তর্ভুক্ত করা ঠিক আছে del module_1মধ্যে __init__.py? আমি কি এইটিকে সার্থক মনে করে ভুল করছি?
মাইক সি

176

আমি ঠিক এটি যুক্ত করতে চাই:

অন্যান্য সমস্ত উত্তর মডিউলগুলি উল্লেখ করে । মূল প্রশ্নটি ফাইলগুলিতে স্পষ্টভাবে উল্লেখ করা __all__হয়েছে __init__.py, সুতরাং এটি পাইথন প্যাকেজগুলির বিষয়ে

সাধারণত, __all__যখন বিবৃতিটির from xxx import *বৈকল্পিক importব্যবহৃত হয় কেবল তখনই খেলতে আসে । এটি প্যাকেজগুলির পাশাপাশি মডিউলগুলির ক্ষেত্রেও প্রযোজ্য।

মডিউলগুলির জন্য আচরণটি অন্য উত্তরে ব্যাখ্যা করা হয়েছে। প্যাকেজগুলির সঠিক আচরণটি বিশদে এখানে বর্ণিত হয়েছে

সংক্ষেপে, __all__প্যাকেজ স্তরে মডিউলগুলির জন্য প্রায় একই কাজ করে, প্যাকেজের অভ্যন্তরে মডিউলগুলির সাথে সম্পর্কিত ( মডিউলটির মধ্যে নাম উল্লেখ করার বিপরীতে )। সুতরাং __all__সমস্ত মডিউল নির্দিষ্ট করে যেগুলি ব্যবহার করা হবে এবং যখন আমরা ব্যবহার করব বর্তমান নেমস্পেসে আমদানি করা হবে from package import *

বড় পার্থক্যটি হ'ল, যখন আপনি কোনও প্যাকেজের ঘোষণাকে বাদ দেন , বিবৃতিটি কিছুতেই আমদানি করবে না (ডকুমেন্টেশনে বর্ণিত ব্যতিক্রম ব্যতীত উপরের লিঙ্কটি দেখুন)।__all____init__.pyfrom package import *

অন্যদিকে, আপনি __all__যদি কোনও মডিউলে বাদ দেন তবে "তারকাচিহ্নিত আমদানি" মডিউলে সংজ্ঞায়িত সমস্ত নাম (আন্ডারস্কোর দিয়ে শুরু নয়) আমদানি করবে।


29
from package import *এখনও নেই __init__.py, এমনকি নির্ধারিত সবকিছু আমদানি করবে all। গুরুত্বপূর্ণ পার্থক্য হ'ল এটি ব্যতীত __all__প্যাকেজ ডিরেক্টরিতে সংজ্ঞায়িত কোনও মডিউল স্বয়ংক্রিয়ভাবে আমদানি করবে না।
নিকরাটিও

যখন সব যদি আমরা ব্যবহার [foo বিন্যাস, বার] এবং test.py ফাইলে রয়েছে: থেকে প্যাকেজ আমদানি *, তারপর, foo বিন্যাস এবং বার test.py বা মধ্যে foo বিন্যাস এবং বার নিজের নামস্থান স্থানীয় নামস্থানে আমদানিকৃত পেতে পারি?
পরিবর্তনশীল

87

এটি পাইডোক কী দেখায় তাও পরিবর্তন করে:

module1.py

a = "A"
b = "B"
c = "C"

module2.py

__all__ = ['a', 'b']

a = "A"
b = "B"
c = "C"

yd পাইডোক মডিউল 1

মডিউল মডিউল 1 এ সহায়তা:

NAME এর
    মডিউল 1

ফাইল
    module1.py

ডেটা 
    a = 'এ'
     বি = 'বি'
     সি = 'সি'

yd পাইডোক মডিউল 2

মডিউল মডিউল 2 এ সহায়তা:

NAME এর
    module2

ফাইল
    module2.py

ডেটা 
    __ সমস্ত__ = ['এ', 'খ']
      = 'এ'
     বি = 'বি'

আমি __all__আমার সমস্ত মডিউলগুলিতে এবং পাশাপাশি অভ্যন্তরীণ বিবরণকে আন্ডারস্কোর করে ঘোষণা করি , লাইভ ইন্টারপ্রেটার সেশনে আপনি আগে কখনও ব্যবহার করেননি এমন জিনিসগুলি ব্যবহার করার সময় এগুলি সত্যই সহায়তা করে।


54

__all__কাস্টমাইজ *ইনfrom <module> import *

__all__কাস্টমাইজ *ইনfrom <package> import *


একটি মডিউল একটি .pyফাইল যা আমদানি করা বোঝায়।

একটি প্যাকেজ একটি __init__.pyফাইল সহ একটি ডিরেক্টরি । একটি প্যাকেজে সাধারণত মডিউল থাকে।


মডিউল

""" cheese.py - an example module """

__all__ = ['swiss', 'cheddar']

swiss = 4.99
cheddar = 3.99
gouda = 10.99

__all__মানুষকে মডিউলটির "সর্বজনীন" বৈশিষ্ট্যগুলি জানতে দেয় । [ @ অ্যারোনহল ] এছাড়াও, পাইডোক তাদের চিনতে পেরেছেন। [ @ লংপোক ]

মডিউল আমদানি থেকে *

স্থানীয় নেমস্পেসে কীভাবে swissএবং কীভাবে cheddarআনা হয় তা দেখুন তবে তা নয় gouda:

>>> from cheese import *
>>> swiss, cheddar
(4.99, 3.99)
>>> gouda
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'gouda' is not defined

ছাড়া __all__, কোনও প্রতীক (এটি আন্ডারস্কোর দিয়ে শুরু হয় না) পাওয়া যেত।


ছাড়া আমদানি *দ্বারা প্রভাবিত হয় না__all__


আমদানি মডিউল

>>> import cheese
>>> cheese.swiss, cheese.cheddar, cheese.gouda
(4.99, 3.99, 10.99)

থেকে মডিউল আমদানি নাম

>>> from cheese import swiss, cheddar, gouda
>>> swiss, cheddar, gouda
(4.99, 3.99, 10.99)

স্থানীয় নাম হিসাবে আমদানি মডিউল

>>> import cheese as ch
>>> ch.swiss, ch.cheddar, ch.gouda
(4.99, 3.99, 10.99)

প্যাকেজ

ইন __init__.pyএকটি ফাইল প্যাকেজ __all__ পাবলিক মডিউল বা অন্যান্য বস্তুর নামের সাথে স্ট্রিং একটি তালিকা রয়েছে। সেই বৈশিষ্ট্যগুলি ওয়াইল্ডকার্ড আমদানিতে উপলব্ধ। মডিউলগুলির মতো, প্যাকেজটি থেকে ওয়াইল্ডকার্ড-আমদানি __all__করার *সময় কাস্টমাইজ করে । [ @ মার্টিনস্টেটনার ]

পাইথন মাইএসকিউএল সংযোগকারীর একটি অংশ এখানে দেওয়া হয়েছে __init__.py:

__all__ = [
    'MySQLConnection', 'Connect', 'custom_error_exception',

    # Some useful constants
    'FieldType', 'FieldFlag', 'ClientFlag', 'CharacterSet', 'RefreshOption',
    'HAVE_CEXT',

    # Error handling
    'Error', 'Warning',

    ...etc...

    ]

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

যদি __all__সংজ্ঞায়িত না করা হয়, বিবৃতিটি প্যাকেজ থেকে সমস্ত সাবমোডিয়ালকে বর্তমান নেমস্পেসে আমদানি from sound.effects import *করে নাsound.effects ; এটি কেবলমাত্র নিশ্চিত করে যে প্যাকেজটি sound.effectsআমদানি করা হয়েছে (সম্ভবত কোনও সূচনা কোড চলমান __init__.py) এবং তারপরে প্যাকেজটিতে যে কোনও নাম সংজ্ঞায়িত করা হয়েছে তা আমদানি করে। এর দ্বারা সংজ্ঞায়িত কোনও নাম অন্তর্ভুক্ত রয়েছে (এবং সাবমডিউলগুলি স্পষ্টভাবে লোড হওয়া) __init__.py। এটিতে প্যাকেজের যে কোনও সাবমডিউল রয়েছে যা পূর্ববর্তী আমদানির বিবৃতিগুলিতে স্পষ্টভাবে লোড করা হয়েছিল।


ওয়াইল্ডকার্ড আমদানি ... এড়ানো উচিত কারণ তারা পাঠক এবং অনেকগুলি স্বয়ংক্রিয় সরঞ্জামাদি বিভ্রান্ত করে।

[ পিইপি ৮ , @ টুলমেকারস্টেভ]


2
আমি সত্যিই এই উত্তর মত, কিন্তু আমি কি ডিফল্ট আচরণ হচ্ছে সে বিষয়ে তথ্য অনুপস্থিত করছি জন্য from <package> import *ছাড়া __all__মধ্যে __init__.pyযে মডিউল কোন আমদানি না
রডজাক

ধন্যবাদ @ জাতিমির, আমি পরীক্ষা-নিরীক্ষা না চালিয়ে যতটা সম্ভব সেরা হিসাবে স্পষ্ট করেছিলাম। আমি প্রায় বলতে চেয়েছিলাম (এই প্যাকেজের জন্য সমস্ত ছাড়াই তারকাচিহ্ন) মডিউল হিসাবে__init__.py একই আচরণ করে । তবে আমি নিশ্চিত নই যে এটি সঠিক, বা বিশেষত যদি আন্ডারস্কোর-উপসর্গযুক্ত জিনিসগুলি বাদ দেওয়া হয়। এছাড়াও, আমি আরও স্পষ্টভাবে মডুলস এবং প্যাকেজগুলিতে বিভাগগুলি পৃথক করেছি। আপনার চিন্তাগুলো?
বব স্টেইন

49

থেকে (একটি বেসরকারী) পাইথন রেফারেন্স উইকি :

মডিউল দ্বারা সংজ্ঞায়িত সর্বজনীন নামগুলি একটি ভেরিয়েবলের জন্য মডিউলটির নাম স্থান পরীক্ষা করে নির্ধারিত হয় __all__; যদি সংজ্ঞায়িত করা হয় তবে এটি অবশ্যই স্ট্রিংয়ের ক্রম হতে হবে যা এই মডিউলটির দ্বারা সংজ্ঞায়িত বা আমদানিকৃত নাম। প্রদত্ত নামগুলি __all__সমস্ত জনসাধারণ হিসাবে বিবেচিত হয় এবং এর উপস্থিতি প্রয়োজন। যদি __all__সংজ্ঞায়িত না করা হয়, সর্বজনীন নামের সেটগুলিতে মডিউলটির নেমস্পেসে পাওয়া সমস্ত নাম অন্তর্ভুক্ত থাকে যা আন্ডারস্কোর অক্ষর ("_") দিয়ে শুরু হয় না। __all__সম্পূর্ণ সর্বজনীন এপিআই থাকা উচিত। এটি দুর্ঘটনাক্রমে আইপিএলের অংশ নয় এমন আইটেম রফতানি এড়ানোর উদ্দেশ্যে করা হয়েছে (যেমন লাইব্রেরী মডিউলগুলি যা মডিউলটির মধ্যে আমদানি করা হয়েছিল এবং ব্যবহৃত হয়েছিল)।


তালিকাভুক্ত লিঙ্কটি মারা গেছে। তবে vdocuments.net/… ও এখানে পাঠ্য শব্দটি পাওয়া গেছে : dokumen.tips/documents/references-567bab8d6118a.html
জয়রিজ্জা

8

__all__পাইথন মডিউলটির সর্বজনীন এপিআই নথি করতে ব্যবহৃত হয়। যদিও এটি alচ্ছিক,__all__ ব্যবহার করা উচিত।

পাইথন ভাষার রেফারেন্সের প্রবন্ধটি এখানে দেওয়া হয়েছে :

মডিউল দ্বারা সংজ্ঞায়িত সর্বজনীন নামগুলি একটি ভেরিয়েবলের জন্য মডিউলটির নাম স্থান পরীক্ষা করে নির্ধারিত হয় __all__; যদি সংজ্ঞায়িত করা হয় তবে এটি অবশ্যই স্ট্রিংয়ের ক্রম হতে হবে যা এই মডিউলটির দ্বারা সংজ্ঞায়িত বা আমদানিকৃত নাম। প্রদত্ত নামগুলি __all__সমস্ত জনসাধারণ হিসাবে বিবেচিত হয় এবং এর উপস্থিতি প্রয়োজন। যদি __all__এটি সংজ্ঞায়িত না করা হয়, সর্বজনীন নামের সেটগুলিতে মডিউলটির নেমস্পেসে পাওয়া সমস্ত নাম অন্তর্ভুক্ত থাকে যা আন্ডারস্কোর অক্ষর ('_') দিয়ে শুরু হয় না। __all__সম্পূর্ণ সর্বজনীন এপিআই থাকা উচিত। এটি দুর্ঘটনাক্রমে আইপিএলের অংশ নয় এমন আইটেম রফতানি এড়ানোর উদ্দেশ্যে করা হয়েছে (যেমন লাইব্রেরী মডিউলগুলি যা মডিউলটির মধ্যে আমদানি করা হয়েছিল এবং ব্যবহৃত হয়েছিল)।

পিইপি 8 অনুরূপ শব্দ ব্যবহার করে, যদিও এটি এও পরিষ্কার করে দেয় যে আমদানি করা নামগুলি __all__অনুপস্থিত থাকলে পাবলিক এপিআইয়ের অংশ নয় :

অন্তর্নির্ধারণের আরও ভাল সমর্থন করার জন্য, মডিউলগুলি স্পষ্টরূপে __all__গুণাবলী ব্যবহার করে তাদের সর্বজনীন API এ নামগুলি প্রকাশ করতে হবে । __all__খালি তালিকায় সেট করা ইঙ্গিত দেয় যে মডিউলের কোনও সার্বিক এপিআই নেই।

[...]

আমদানিকৃত নামগুলি সর্বদা একটি প্রয়োগের বিশদ হিসাবে বিবেচনা করা উচিত। অন্যান্য মডিউলগুলি অবশ্যই এগুলি আমদানিকৃত নামগুলিতে অপ্রত্যক্ষ অ্যাক্সেসের উপর নির্ভর করবে না যতক্ষণ না তারা মডিউলটির এপিআই এর একটি স্পষ্টভাবে দলিলযুক্ত অংশ না হয়, যেমন os.pathপ্যাকেজের __init__মডিউল যা সাবমোডিয়ুলগুলি থেকে কার্যকারিতা প্রকাশ করে।

তদ্ব্যতীত, অন্যান্য উত্তরে যেমন উল্লেখ করা হয়েছে, প্যাকেজগুলির জন্য ওয়াইল্ডকার্ড আমদানি__all__ সক্ষম করতে ব্যবহৃত হয় :

আমদানি বিবৃতিটি নিম্নলিখিত কনভেনশনটি ব্যবহার করে: যদি প্যাকেজের __init__.pyকোড নামের তালিকাটি সংজ্ঞায়িত __all__করে তবে মডিউল নামের তালিকা হিসাবে নেওয়া হবে from package import *যা সম্মুখীন হওয়ার পরে আমদানি করা উচিত ।


8

সংক্ষিপ্ত উত্তর

__all__from <module> import *বিবৃতি প্রভাবিত করে ।

দীর্ঘ উত্তর

এই উদাহরণ বিবেচনা করুন:

foo
├── bar.py
└── __init__.py

ইন foo/__init__.py:

  • (অন্তর্ভুক্ত) যদি আমরা সংজ্ঞায়িত না করি __all__তবে from foo import *কেবলমাত্র সংজ্ঞায়িত নামগুলি আমদানি করবে foo/__init__.py

  • (স্পষ্টত) যদি আমরা সংজ্ঞায়িত করি __all__ = []তবে from foo import *কিছুই আমদানি করবে না।

  • (স্পষ্টত) যদি আমরা সংজ্ঞায়িত করি __all__ = [ <name1>, ... ]তবে from foo import *কেবলমাত্র সেগুলি নামগুলি আমদানি করবে।

নোট করুন যে অন্তর্নিহিত ক্ষেত্রে পাইথন দিয়ে শুরু হওয়া নাম আমদানি করবে না _। তবে আপনি ব্যবহার করে এ জাতীয় নাম আমদানি করতে বাধ্য করতে পারেন__all__

আপনি পাইথন ডকুমেন্টটি এখানে দেখতে পারেন ।


5

__all__কীভাবে from foo import *কাজ করে তা প্রভাবিত করে।

মডিউল বডিটির ভিতরে থাকা কোড (তবে কোনও ফাংশন বা শ্রেণীর শরীরে নয় *) একটি fromবিবৃতিতে একটি তারকাচিহ্ন ( ) ব্যবহার করতে পারে :

from foo import *

যে *অনুরোধগুলি মডিউলের সমস্ত বৈশিষ্ট্যগুলি foo(আন্ডারস্কোরগুলি দিয়ে শুরু করে ব্যতীত) আমদানি করা মডিউলে গ্লোবাল ভেরিয়েবল হিসাবে আবদ্ধ। যখন fooকোনও অ্যাট্রিবিউট থাকে __all__, বৈশিষ্ট্যের মান হ'ল নামগুলির তালিকা যা এই ধরণের দ্বারা আবদ্ধ থাকেfrom বিবৃতি ।

যদি fooকোনও প্যাকেজ হয় এবং এটি __init__.pyনামের তালিকাটি সংজ্ঞায়িত __all__করে তবে এটি সাবমডিউলের নামের তালিকা হিসাবে নেওয়া হবে from foo import *যা সম্মুখীন হওয়ার পরে আমদানি করা উচিত । যদি __all__সংজ্ঞায়িত না করা হয়, বিবৃতি from foo import *প্যাকেজটিতে যে কোনও নাম সংজ্ঞায়িত করা হয়েছে তা আমদানি করে। এর দ্বারা সংজ্ঞায়িত কোনও নাম অন্তর্ভুক্ত রয়েছে (এবং সাবমডিউলগুলি স্পষ্টভাবে লোড হওয়া) __init__.py

নোট করুন যে __all__একটি তালিকা হতে হবে না। importবিবৃতিতে ডকুমেন্টেশন অনুসারে , যদি সংজ্ঞায়িত করা হয় তবে __all__অবশ্যই স্ট্রিংগুলির ক্রম হতে হবে যা মডিউল দ্বারা সংজ্ঞায়িত বা আমদানিকৃত নাম। সুতরাং আপনি কিছু মেমরি এবং সিপিইউ চক্র সংরক্ষণ করতে একটি টুপল ব্যবহার করতে পারেন । মডিউলটি একটি একক সার্বজনীন নাম সংজ্ঞায়িত করার ক্ষেত্রে কেবল কমাটি ভুলে যাবেন না:

__all__ = ('some_name',)

আরও দেখুন কেন "আমদানি *" খারাপ?


1

এটি এখানে PEP8 এ সংজ্ঞায়িত করা হয়েছে :

গ্লোবাল ভেরিয়েবল নাম

(আসুন আমরা আশা করি যে এই পরিবর্তনকগুলি কেবল একটি মডিউলের অভ্যন্তরে ব্যবহারের জন্য বোঝানো হয়েছে)) সম্মেলনগুলি কার্যকারিতা হিসাবে প্রায় একই রকম।

মডিউলগুলি যেগুলির মাধ্যমে ব্যবহারের জন্য ডিজাইন করা হয়েছে তাদের গ্লোবালগুলি রফতানি রোধ from M import *করতে __all__মেকানিজম ব্যবহার করা উচিত , বা আন্ডারস্কোর দিয়ে এই ধরনের গ্লোবালগুলির উপসর্গের পুরানো কনভেনশন ব্যবহার করা উচিত (যা আপনি এই গ্লোবালগুলি বোঝাতে চাইবেন "মডিউল নন-পাবলিক")।

পিইপি 8 মূল পাইথন বিতরণে স্ট্যান্ডার্ড লাইব্রেরি সমন্বিত পাইথন কোডের কোডিং কনভেনশন সরবরাহ করে। আপনি এটিকে যত বেশি অনুসরণ করেন, ততই আপনি আসল অভিপ্রায়ের নিকটবর্তী হন।

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