मैं अच्छा / सही पैकेज __init__.py फ़ाइलों को कैसे लिखूँ


187

मेरे पैकेज में निम्नलिखित संरचना है:

mobilescouter/
    __init__.py #1
    mapper/
        __init__.py  #2
        lxml/
            __init__.py #3
            vehiclemapper.py
            vehiclefeaturemapper.py
            vehiclefeaturesetmapper.py
        ...
        basemapper.py
   vehicle/
        __init__.py #4
        vehicle.py
        vehiclefeature.py
        vehiclefeaturemapper.py
   ...

मुझे यकीन नहीं है कि __init__.pyफ़ाइलों को सही तरीके से कैसे लिखा जाना चाहिए।
इस __init__.py #1तरह दिखता है:

__all__ = ['mapper', 'vehicle']
import mapper
import vehicle

लेकिन उदाहरण के लिए कैसा दिखना चाहिए __init__.py #2? मेरा है:

__all__ = ['basemapper', 'lxml']
from basemaper import *
import lxml

कब __all__इस्तेमाल किया जाना चाहिए ?


2
ध्यान रखें कि कोड में * आयात का उपयोग करना आमतौर पर बहुत बुरा व्यवहार है और यदि संभव हो तो इसे टाला जाना चाहिए। इसके लिए बहुत कम उपयोग के मामले हैं, लेकिन वे वास्तव में दुर्लभ हैं।
मयउ36

पीएसए: यदि आप अच्छे नेमस्पेस पैकेज (नए तरह का पैकेज) लिखना सीखना चाहते हैं, तो इस उदाहरण पैकेज को देखें: github.com/pypa/sample-namespace-packages
Kyle

जवाबों:


145

__all__ बहुत अच्छा है - यह मॉड्यूल को स्वचालित रूप से आयात किए बिना आयात विवरणों को निर्देशित करने में मदद करता है http://docs.python.org/tutorial/modules.html#importing-from-a-package

उपयोग करना __all__और import *निरर्थक है, केवल__all__ जरूरत है

मुझे लगता है कि एक आयात पैकेज import *में उपयोग करने के लिए सबसे शक्तिशाली कारणों में से एक __init__.pyहै कि एक मौजूदा अनुप्रयोग को तोड़ने के बिना कई लिपियों में हो गई एक स्क्रिप्ट को फिर से सक्रिय करने में सक्षम होना चाहिए। लेकिन अगर आप शुरू से ही पैकेज डिजाइन कर रहे हैं। मुझे लगता है कि __init__.pyफाइलों को खाली छोड़ना सबसे अच्छा है ।

उदाहरण के लिए:

foo.py - contains classes related to foo such as fooFactory, tallFoo, shortFoo

तब ऐप बढ़ता है और अब यह एक संपूर्ण फ़ोल्डर है

foo/
    __init__.py
    foofactories.py
    tallFoos.py
    shortfoos.py
    mediumfoos.py
    santaslittlehelperfoo.py
    superawsomefoo.py
    anotherfoo.py

तब init स्क्रिप्ट कह सकती है

__all__ = ['foofactories', 'tallFoos', 'shortfoos', 'medumfoos',
           'santaslittlehelperfoo', 'superawsomefoo', 'anotherfoo']
# deprecated to keep older scripts who import this from breaking
from foo.foofactories import fooFactory
from foo.tallfoos import tallFoo
from foo.shortfoos import shortFoo

ताकि परिवर्तन के दौरान निम्नलिखित करने के लिए लिखी गई स्क्रिप्ट न टूटे:

from foo import fooFactory, tallFoo, shortFoo

3
मैं ' ऑल ' और लाइन बाई लाइन इम्पोर्ट के बारे में बहुत उलझन में था। आपका उदाहरण बहुत ही रोशन करने वाला है।
जंचेन

2
मैं " __all__और import *निरर्थक हूं" से भ्रमित हूं , __all__इसका उपयोग मॉड्यूल के उपभोक्ता द्वारा किया जाता है, और from foo import *मॉड्यूल द्वारा खुद को दूसरों का उपयोग करने के लिए उपयोग किया जाता है ....
Nick T

using __all__ and import * is redundant, only __all__ is needed वे कैसे बेमानी हैं? वे अलग-अलग काम करते हैं।
एंडोलिथ

112

मेरी अपनी __init__.pyफाइलें अक्सर नहीं की तुलना में अधिक खाली हैं। विशेष रूप से, मेरे पास कभी भी इसका एक from blah import *हिस्सा नहीं है __init__.py- अगर "पैकेज का आयात करना" का अर्थ है सभी प्रकार की कक्षाएं, फ़ंक्शंस आदि को सीधे पैकेज के हिस्से के रूप में परिभाषित करना, तो मैं blah.pyपैकेज के __init__.pyबदले में सामग्री को कॉपी करूँगा और हटा दूंगा blah.py() स्रोत फ़ाइलों का गुणन यहाँ अच्छा नहीं है)।

यदि आप import *मुहावरों (eek) का समर्थन करने पर जोर देते हैं , तो उपयोग __all__(क्षति के नाम की सूची के रूप में आप अपने आप को इसमें लाने के लिए कर सकते हैं) क्षति नियंत्रण के लिए मदद कर सकते हैं। सामान्य तौर पर, नाम स्थान और स्पष्ट आयात अच्छी चीजें हैं, और मैं किसी भी दृष्टिकोण या दोनों अवधारणाओं को व्यवस्थित रूप से आधारित किसी भी दृष्टिकोण पर पुनर्विचार करने का सुझाव देता हूं! -)


9
व्यक्तिगत रूप से, मैं चीजों को अलग रखना पसंद करता हूं, और फिर * आयात करता हूं। इसका कारण यह है कि, तह और सामान के बावजूद, मुझे अभी भी बहुत सारी कक्षाओं वाली फ़ाइलों को ब्राउज़ करने से नफरत है, भले ही संबंधित हों।
स्टेफानो बोरीनी

5
@ स्टेफानो एक बड़े ढांचे के बारे में सोचते हैं। यदि यह उपयोग करता है import *तो आपको बिना शर्त इसके सभी ढांचे को स्वीकार करना चाहिए, यहां तक ​​कि उन विशेषताओं को भी जिन्हें आप कभी उपयोग नहीं करेंगे। __init__.pyखाली रखने से आपको केवल ऑल-ऑल-और कुछ नहीं शब्दार्थ से अधिक मौके मिलते हैं। मुड़ के बारे में सोचो।
मिलीग्राम।

यदि आयात मोबाइल फोन राउटर के बाद भी इसे खाली रखा जाता है, तो एक मोबिलकाउटर, टैपर या मोबिलकाउटर.व्हील या मोबिलकाउटर.व्हीटवर का उपयोग नहीं कर सकता है। mobilescouter.A को आयात नहीं किया जाता है, mobilescouter.B ..... बहुत क्रिया?
सनकिआंग

6
@sunqiang यह व्यक्तिगत है, लेकिन मुझे ऐसा नहीं लगता। from mobilescouter import A, Bसिर्फ कोड की एक पंक्ति है और आप 666 वर्गों और हर एक के पास अपनी फ़ाइल के साथ एक परियोजना नहीं है, है ना? यदि आपके पास import *अपने कोड में दो या अधिक हैं तो आप संभावित कचरे के साथ नाम स्थान को भर रहे हैं और जल्दी से भूल जाएंगे कि आप कहां से Aआए हैं। और अगर एक ऊपरी पैकेज भी ऐसा ही करता है? आप सभी उप-पैकेजों और उप-उप-पैकेजों को हथिया रहे हैं। जैसे अजगर का ज़ेन कहता है, स्पष्ट रूप से निहित से बेहतर है।
मिलीग्राम।

1
@mg, अगर init .py फ़ाइल में एक लाइन "आयात A, B" है , तो मैं वाक्य रचना के साथ A (या B) कॉल कर सकता हूं: mobilescouter.A; अगर हम "मोबाइल फोन के आयात से A, B" का उपयोग करते हैं, तो यह सिर्फ A.something है। कभी-कभी यह लाइन, मुझे याद नहीं है कि ए मोबाइल मोबाइल के राउटर का उप-पैक है, और मुझे लगता है कि यह नेमस्पेस प्रदूषण में योगदान देता है (हालांकि यह मोबाइल फोन के आयात से "" की तुलना में बहुत बेहतर है। "" मैं अभी भी "pkgname" आयात उपयोगकर्ता को पसंद करता हूं) समान सार्वजनिक इंटरफ़ेस। इसलिए init .py आयात sub_pkgname चीजों को करते हैं।
sunqiang

1

आपके __init__.pyपास एक डॉकस्ट्रिंग होना चाहिए ।

यद्यपि सभी कार्यक्षमता मॉड्यूल और उप-पैकेजों में कार्यान्वित की जाती है, आपका पैकेज डॉकस्ट्रिंग दस्तावेज़ को शुरू करने का स्थान है। उदाहरण के लिए, अजगर emailपैकेज पर विचार करें । पैकेज प्रलेखन एक उद्देश्य, पृष्ठभूमि, और पैकेज के भीतर विभिन्न घटकों के एक साथ काम करने का वर्णन करता है। यदि आप स्वचालित रूप से स्फिंक्स या किसी अन्य पैकेज का उपयोग करते हुए डॉकस्ट्रिंग से प्रलेखन उत्पन्न करते हैं, तो इस तरह के परिचय का वर्णन करने के लिए पैकेज डॉकस्ट्रिंग बिल्कुल सही जगह है।

किसी भी अन्य सामग्री के लिए, फायरक्रू और एलेक्स मार्टेली द्वारा उत्कृष्ट उत्तर देखें ।


क्या पैकेज के __init__.pyलिए वास्तविक emailइस दिशानिर्देश का पालन करता है? मुझे एक एकल पंक्ति दिखाई दे रही है जो यह समझाने के लिए बहुत कुछ नहीं करती है कि "पैकेज के भीतर विभिन्न घटक एक साथ कैसे काम करते हैं"।
गर्ट्लेक्स

@Gertlex केवल वेब प्रलेखन में हो सकता है।
Gerrit
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.