जवाबों:
यह उस मॉड्यूल की सार्वजनिक वस्तुओं की सूची है, जिसकी व्याख्या की गई है import *
। यह एक अंडरस्कोर से शुरू होने वाली हर चीज को छिपाने के डिफ़ॉल्ट को ओवरराइड करता है।
import *
(जैसे कि उदाहरण के लिए tk
)। एक अच्छा संकेत अगर यह मामला है __all__
या मॉड्यूल के कोड में अंडरस्कोर के साथ शुरू होने वाले नामों की उपस्थिति है ।
tk
आज (या 2012 में, यहां तक कि) जारी किए गए थे, तो अनुशंसित अभ्यास का उपयोग करना होगा from tk import *
। मुझे लगता है कि अभ्यास को जड़ता के कारण स्वीकार किया जाता है, न कि जानबूझकर डिजाइन के कारण।
से जुड़ा हुआ है, लेकिन यहाँ स्पष्ट रूप से उल्लेख नहीं किया गया है, वास्तव में जब __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-package
नोट: केवल व्यवहार को __all__
प्रभावित करता है from <module> import *
। __all__
जिन सदस्यों का उल्लेख नहीं किया गया है वे अभी भी मॉड्यूल के बाहर से सुलभ हैं और इसके साथ आयात किया जा सकता है from <module> import <member>
।
print(baz())
?
print(baz)
कुछ प्रिंट करता है <function baz at 0x7f32bc363c10>
जबकि print(baz())
प्रिंटbaz
पायथन में __all__ समझाओ?
मैं
__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__
लिए घोषणा करने वाले सबपैकेज के लिए s बनाएँ :
(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>
और आप आसानी से अपने एपीआई में उन चीजों को जोड़ सकते हैं जिन्हें आप उप-पैकेज के मॉड्यूल स्तर के बजाय उप-पैकेज स्तर पर प्रबंधित कर सकते हैं। यदि आप एपीआई में एक नया नाम जोड़ना चाहते हैं, तो आप बस __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()
लेकिन अगर वे इसके बारे में नहीं जानते हैं, तो अन्य उपकरण (जैसे pydoc ) उन्हें सूचित नहीं करेंगे।
बाद में Baz
प्राइम टाइम के लिए तैयार होने पर आप इसे बदल सकते हैं :
from .module_1 import *
from .module_2 import *
__all__ = ['foo', 'Bar', 'Baz']
_
बनाम __all__
:डिफ़ॉल्ट रूप से, पायथन उन सभी नामों को निर्यात करेगा जो किसी के साथ शुरू नहीं होते हैं _
। आप निश्चित रूप से इस तंत्र पर भरोसा कर सकते हैं। पायथन मानक पुस्तकालय में कुछ पैकेज, वास्तव में, इस पर भरोसा करते हैं, लेकिन ऐसा करने के लिए, वे अपने आयातों को उर्फ करते हैं, उदाहरण के लिए ctypes/__init__.py
:
import os as _os, sys as _sys
_
सम्मेलन का उपयोग करना अधिक सुरुचिपूर्ण हो सकता है क्योंकि यह नामों को फिर से नाम देने की अतिरेक को दूर करता है। लेकिन यह आयातों के लिए अतिरेक जोड़ता है (यदि आपके पास उनमें से बहुत कुछ है) और इसे लगातार करना भूल जाना आसान है - और आखिरी चीज जो आप चाहते हैं वह है अनिश्चित काल के लिए कुछ का समर्थन करना जिसका आप केवल कार्यान्वयन विवरण होना चाहते हैं, बस क्योंकि आप _
किसी फ़ंक्शन का नामकरण करते समय उपसर्ग करना भूल गए थे ।
मैं व्यक्तिगत रूप से __all__
मॉड्यूल के लिए अपने विकास के जीवन चक्र में एक शुरुआती लिखता हूं ताकि जो लोग मेरे कोड का उपयोग कर सकते हैं वे जान सकें कि उन्हें क्या उपयोग करना चाहिए और क्या नहीं।
मानक पुस्तकालय में अधिकांश पैकेज भी उपयोग करते हैं __all__
।
__all__
समझ में आता हैजब इसके _
बदले में उपसर्ग सम्मेलन से चिपके रहना समझ में आता है __all__
:
export
डेकोरेटरउपयोग करने __all__
का नकारात्मक पक्ष यह है कि आपको दो बार निर्यात किए जा रहे कार्यों और वर्गों के नाम लिखने होते हैं - और जानकारी को परिभाषाओं से अलग रखा जाता है। हम इस समस्या को हल करने के लिए डेकोरेटर का उपयोग कर सकते हैं।
मुझे पैकेजिंग पर डेविड बेज़ले की बात से इस तरह के एक निर्यात सज्जाकार के लिए विचार मिला। यह कार्यान्वयन सीपीथॉन के पारंपरिक आयातक में अच्छा काम करता है। यदि आपके पास एक विशेष आयात हुक या सिस्टम है, तो मैं इसकी गारंटी नहीं देता, लेकिन यदि आप इसे अपनाते हैं, तो इसे वापस करने के लिए काफी तुच्छ है - आपको केवल नामों को मैन्युअल रूप से वापस जोड़ने की आवश्यकता होगी__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
@export
डेकोरेटर कैसे लिखें ।
__init__.py
और के उपयोग__all__
__all__
यह सही है।
__all__
भी उत्पन्न करना चाहिए - लेकिन फिर मैं कहूंगा कि आपके पास एक अस्थिर एपीआई है ... यह कुछ व्यापक स्वीकृति परीक्षणों के लिए कुछ होगा।
module_1
और module_2
; यह एक स्पष्ट शामिल करने के लिए ठीक है del module_1
में __init__.py
? क्या मैं यह सोचने के लिए गलत हूँ कि यह सार्थक है?
मैं इसे सटीक होने के लिए जोड़ रहा हूं:
अन्य सभी उत्तर मॉड्यूल को संदर्भित करते हैं । मूल प्रश्न का स्पष्ट रूप __all__
से __init__.py
फाइलों में उल्लेख किया गया है, इसलिए यह अजगर पैकेज के बारे में है ।
आम तौर पर, __all__
केवल तभी खेल में आता है जब कथन के from xxx import *
प्रकार का import
उपयोग किया जाता है। यह पैकेज के साथ-साथ मॉड्यूल पर भी लागू होता है।
मॉड्यूल के व्यवहार को अन्य उत्तरों में समझाया गया है। संकुल के लिए सटीक व्यवहार यहाँ विस्तार से वर्णित है ।
संक्षेप में, __all__
पैकेज स्तर मॉड्यूल के लिए लगभग एक ही काम करता है, सिवाय इसके कि यह पैकेज के भीतर मॉड्यूल के साथ काम करता है ( मॉड्यूल के भीतर निर्दिष्ट नामों के विपरीत )। इसलिए __all__
उन सभी मॉड्यूल्स को निर्दिष्ट करता है जो हमारे द्वारा उपयोग किए जाने पर वर्तमान नामस्थान में लोड और आयात किए जाएंगे from package import *
।
बड़ा अंतर यह है, कि जब आप किसी पैकेज की घोषणा को छोड़ देते हैं , तो कथन कुछ भी आयात नहीं करेगा (प्रलेखन में वर्णित अपवादों के साथ, ऊपर लिंक देखें)।__all__
__init__.py
from package import *
दूसरी ओर, यदि आप __all__
एक मॉड्यूल में छोड़ देते हैं , तो "तारांकित आयात" मॉड्यूल में परिभाषित सभी नामों (एक अंडरस्कोर के साथ शुरू नहीं) को आयात करेगा।
from package import *
अभी भी परिभाषित सब कुछ आयात करेगा __init__.py
, भले ही कोई भी क्यों न हो all
। महत्वपूर्ण अंतर यह है कि इसके बिना __all__
पैकेज की निर्देशिका में परिभाषित किसी भी मॉड्यूल को स्वचालित रूप से आयात नहीं किया जाएगा।
यह भी बदलता है कि pydoc क्या दिखाएगा:
module1.py
a = "A"
b = "B"
c = "C"
module2.py
__all__ = ['a', 'b']
a = "A"
b = "B"
c = "C"
$ pydoc मॉड्यूल 1
मॉड्यूल मॉड्यूल 1 पर मदद: नाम मॉड्यूल 1 फ़ाइल module1.py DATA a = 'A' b = 'B' c = 'C'
$ pydoc मॉड्यूल 2
मॉड्यूल मॉड्यूल 2 पर मदद: नाम module2 फ़ाइल module2.py DATA __all__ = ['a', 'b'] a = 'A' b = 'B'
मैं अपने __all__
सभी मॉड्यूलों में घोषणा करता हूं, साथ ही आंतरिक विवरणों को भी रेखांकित करता हूं, ये उन चीजों का उपयोग करते समय मदद करते हैं जिन्हें आपने पहले कभी भी लाइव इंटरप्रिटेशन सत्रों में उपयोग नहीं किया है।
__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__
मानव को मॉड्यूल की "सार्वजनिक" विशेषताओं को जानने देता है । [ @AaronHall ] इसके अलावा, pydoc उन्हें पहचानता है। [ @Longpoke ]
देखें कि कैसे 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
फाइल में सार्वजनिक मॉड्यूल या अन्य वस्तुओं के नाम के साथ तार की एक सूची है। वे सुविधाएँ वाइल्डकार्ड आयात के लिए उपलब्ध हैं। मॉड्यूल के साथ, पैकेज से वाइल्डकार्ड-आयात करते समय कस्टमाइज़ करता है । [ @MartinStettner ] __all__
__all__
*
यहाँ पायथन MySQL कनेक्टर से एक अंश है __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
वाइल्डकार्ड आयात ... से बचना चाहिए क्योंकि वे [भ्रमित] पाठक और कई स्वचालित उपकरण हैं।
[ पीईपी 8 , @ टूलमेकरसैटवे]
from <package> import *
बिना डिफ़ॉल्ट व्यवहार क्या है, किसी भी मॉड्यूल को आयात नहीं कर रहा है । __all__
__init__.py
__init__.py
एक मॉड्यूल था । लेकिन मुझे यकीन नहीं है कि यह सटीक है, या विशेष रूप से यदि अंडरस्कोर-उपसर्गित वस्तुओं को बाहर रखा गया है। इसके अलावा, मैंने मॉड्यूल और पैकेज पर वर्गों को और अधिक स्पष्ट रूप से अलग कर दिया है। तुम्हारे विचार?
से (एक अनौपचारिक) पायथन संदर्भ विकी :
एक मॉड्यूल द्वारा परिभाषित सार्वजनिक नाम एक चर नाम के लिए मॉड्यूल के नाम स्थान की जांच करके निर्धारित किए जाते हैं
__all__
; यदि परिभाषित किया गया है, तो यह उन तारों का एक अनुक्रम होना चाहिए, जो उस मॉड्यूल द्वारा परिभाषित या आयातित नाम हैं। जिन नामों को दिया गया है,__all__
वे सभी सार्वजनिक माने जाते हैं और उनका अस्तित्व होना आवश्यक है। यदि__all__
परिभाषित नहीं किया गया है, तो सार्वजनिक नामों के सेट में मॉड्यूल के नामस्थान में पाए जाने वाले सभी नाम शामिल हैं जो अंडरस्कोर वर्ण ("_") से शुरू नहीं होते हैं।__all__
संपूर्ण सार्वजनिक API होना चाहिए। यह गलती से निर्यात की जाने वाली वस्तुओं से बचने का इरादा है जो एपीआई का हिस्सा नहीं हैं (जैसे पुस्तकालय मॉड्यूल जो आयात किए गए थे और मॉड्यूल के भीतर उपयोग किए गए थे)।
__all__
इसका उपयोग पायथन मॉड्यूल के सार्वजनिक एपीआई के दस्तावेज के लिए किया जाता है। हालांकि यह वैकल्पिक है, __all__
इसका उपयोग किया जाना चाहिए।
यहाँ पाइथन भाषा के संदर्भ से संबंधित अंश प्रस्तुत है :
एक मॉड्यूल द्वारा परिभाषित सार्वजनिक नाम एक चर नाम के लिए मॉड्यूल के नाम स्थान की जांच करके निर्धारित किए जाते हैं
__all__
; यदि परिभाषित किया गया है, तो यह उन तारों का एक अनुक्रम होना चाहिए, जो उस मॉड्यूल द्वारा परिभाषित या आयातित नाम हैं। जिन नामों को दिया गया है,__all__
वे सभी सार्वजनिक माने जाते हैं और उनका अस्तित्व होना आवश्यक है। यदि__all__
परिभाषित नहीं किया गया है, तो सार्वजनिक नामों के सेट में मॉड्यूल के नामस्थान में पाए जाने वाले सभी नाम शामिल हैं जो अंडरस्कोर वर्ण ('_') से शुरू नहीं होते हैं।__all__
संपूर्ण सार्वजनिक API होना चाहिए। यह गलती से निर्यात की जाने वाली वस्तुओं से बचने का इरादा है जो एपीआई का हिस्सा नहीं हैं (जैसे पुस्तकालय मॉड्यूल जो आयात किए गए थे और मॉड्यूल के भीतर उपयोग किए गए थे)।
PEP 8 इसी तरह के शब्दों का उपयोग करता है, हालांकि यह भी स्पष्ट करता है कि __all__
अनुपस्थित होने पर आयातित नाम सार्वजनिक API का हिस्सा नहीं हैं:
आत्मनिरीक्षण का बेहतर समर्थन करने के लिए, मॉड्यूल को स्पष्ट रूप से
__all__
विशेषता का उपयोग करके अपने सार्वजनिक एपीआई में नामों की घोषणा करनी चाहिए ।__all__
खाली सूची पर सेट करना दर्शाता है कि मॉड्यूल में कोई सार्वजनिक एपीआई नहीं है।[...]
आयातित नामों को हमेशा एक कार्यान्वयन विवरण माना जाना चाहिए। अन्य मॉड्यूल को ऐसे आयातित नामों के अप्रत्यक्ष उपयोग पर भरोसा नहीं करना चाहिए जब तक कि वे मॉड्यूल के एपीआई युक्त एक स्पष्ट रूप से प्रलेखित हिस्सा नहीं हैं, जैसे कि
os.path
या एक पैकेज का__init__
मॉड्यूल जो सबमॉड्यूल से कार्यक्षमता को उजागर करता है।
इसके अलावा, जैसा कि अन्य उत्तरों में बताया गया है, पैकेज के लिए आयात होने वाले वाइल्डकार्ड__all__
को सक्षम करने के लिए उपयोग किया जाता है :
आयात विवरण निम्न सम्मेलन का उपयोग करता है: यदि पैकेज का
__init__.py
कोड नाम की सूची को परिभाषित करता है__all__
, तो इसे मॉड्यूल नामों की सूची के रूप में लिया जाता है, जिनकाfrom package import *
सामना होने पर आयात किया जाना चाहिए ।
__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__
।
__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',)
यह भी देखें कि "आयात *" बुरा क्यों है?
इसे यहाँ PEP8 में परिभाषित किया गया है :
वैश्विक चर नाम
(चलो आशा करते हैं कि ये चर केवल एक मॉड्यूल के अंदर उपयोग के लिए हैं।) कन्वेंशन उन कार्यों के लिए समान हैं।
मॉड्यूल जिनके माध्यम से उपयोग के लिए डिज़ाइन किए गए हैं , उन्हें ग्लोबल्स के निर्यात को रोकने के
from M import *
लिए__all__
तंत्र का उपयोग करना चाहिए , या अंडरस्कोर के साथ ऐसे ग्लोबल्स को प्रीफ़िक्स करने के पुराने सम्मेलन का उपयोग करना चाहिए (जो कि आप इन ग्लोबल्स को इंगित करने के लिए करना चाहते हैं "मॉड्यूल गैर-सार्वजनिक हैं)।"
PEP8 पायथन कोड के लिए कोडिंग कन्वेंशन प्रदान करता है जिसमें मुख्य पायथन वितरण में मानक पुस्तकालय शामिल है। जितना अधिक आप इसका अनुसरण करते हैं, आप मूल इरादे के करीब हैं।
__all__
यदि__all__
मौजूद हैं, तो उनका उल्लेख नहीं किया जाता है, वे वास्तव में छिपी नहीं हैं; यदि आप उनके नाम जानते हैं तो उन्हें सामान्य रूप से पूरी तरह से देखा और एक्सेस किया जा सकता है। यह केवल एक "आयात *" के मामले में है, जिसे वैसे भी अनुशंसित नहीं किया जाता है, जो कि अंतर किसी भी भार को वहन करता है।