2014-06-17 4 views
10

मैं python3 में ऑब्जेक्ट उन्मुख मॉडल के बाद मेरी कंपनी के लिए एक जटिल अनुप्रयोग विकसित कर रहा हूं। एप्लिकेशन में कई संकुल और उप-पैकेज होते हैं, प्रत्येक - ज़ाहिर है - जिसमें __init__.py मॉड्यूल होता है।क्या यह सामान्य, अमूर्त कक्षाओं के लिए पैकेज के __init__.py मॉड्यूल का उपयोग करने के लिए पाइथोनिक है?

मैंने ज्यादातर उन __init__.py मॉड्यूल का उपयोग उन पैकेजों के लिए सामान्य वर्ग घोषित करने के लिए किया था, जिनका उद्देश्य केवल उनके संबंधित पैकेज के लिए सार टेम्पलेट्स के रूप में उपयोग किया जाना है।

मेरा प्रश्न अब है: क्या यह __init__.py मॉड्यूल का उपयोग करने के लिए "अच्छा"/"सही"/"पायथनिक" तरीका है? या मैं अपने जेनेरिक कक्षाओं को कहीं और घोषित करूंगा?

mypkg.__init__.py:

class Foo(object): 
    __some_attr = None 

    def __init__(self, some_attr): 
     self.__some_attr = some_attr 

    @property 
    def some_attr(self): 
     return self.__some_attr 

    @some_attr.setter 
    def some_attr(self, val): 
     self.__some_attr = val 

mypkg.myfoo.py:

एक उदाहरण देने के लिए, के एक पैकेज mypkg मान लें

from . import Foo 

class MyFoo(Foo): 
    def __init__(self): 
     super().__init__("this is my implemented value") 

    def printme(self): 
     print(self.some_attr) 
+5

क्या आपका वर्तमान दृष्टिकोण किसी भी सिरदर्द का कारण बनता है? कुछ ठीक कर रहा है जो ठीक काम कर रहा है क्योंकि कोई इसे मान सकता है कि यह अवांछित है। – timgeb

+0

मैंने हमेशा '__init __। Py' के बारे में सोचा, यदि किसी भी चीज़ के लिए उपयोग किया जाता है, मॉड्यूल प्रारंभिक (जैसे मॉड्यूल-वाइड स्टेट ऑब्जेक्ट्स इत्यादि बनाना) और मॉड्यूल के सार्वजनिक इंटरफ़ेस को प्रस्तुत करने के लिए। इसके बारे में सोचने का एक और तरीका, मुझे लगता है कि, '__init __। Py' मॉड्यूल ऑब्जेक्ट के लिए समान भूमिका निभाता है जब मॉड्यूल को' __init __() 'विधि के रूप में आयात किया जाता है, जो कि एक नव निर्मित उदाहरण के लिए करता है कक्षा। –

+0

@timgeb कोई भी तकनीकी या अवधारणात्मक समस्या नहीं है। आवेदन ठीक काम करता है। फिर भी मैं अजगर के लिए नया हूं और अब पीईपी का पालन करने के लिए सामान साफ ​​करना चाहता हूं। @ सिलसरे तो फिर आपका प्रस्ताव क्या है? क्या मैं अमूर्त कक्षाओं को कुछ मॉड्यूल 'abstract.py' या 'templates.py' में रखूंगा? –

उत्तर

4

यह निर्भर करता है कि आप कौन सी एपीआई प्रदान करना चाहते हैं। उदाहरण के लिए मानक पुस्तकालय में collections मॉड्यूल __init__.py में सभी कक्षाओं को परिभाषित करता है। और मानक पुस्तकालय सुंदर "पायथनिक" होना चाहिए, जो भी इसका मतलब है।

हालांकि यह ज्यादातर "मॉड्यूल-जैसे" इंटरफ़ेस प्रदान करता है। यह देखने के लिए बहुत दुर्लभ है:

import collections.abc 

यदि आपके पास पहले से ही उप-पैकेज हैं तो आप शायद एक नया सबपैकेज शुरू कर रहे हैं। यदि वर्तमान में, पैकेज का उपयोग वास्तव में उन उप-पैकेजों पर निर्भर नहीं करता है जिन्हें आप __init__.py में कोड डालने पर विचार कर सकते हैं। या फिर कुछ निजी मॉड्यूल में कोड डाल दिया और बस __init__.py अंदर नाम आयात (यह क्या मैं 'डी पसंद करते है)


आप केवल जहां यह सार आधार वर्ग डाल करने के लिए बेहतर है को लेकर चिंतित हैं, के रूप में अगर ऊपर दिखाया गया है (collections.abc में collections पैकेज का सार आधार वर्ग शामिल है), और जैसा कि आप मानक लाइब्रेरी के abc मॉड्यूल से देख सकते हैं, उनमें abc.py सबमिशन को परिभाषित करना आम बात है। आप उन्हें __init__.py करने से सीधे उजागर विचार कर सकते हैं:

from .abc import * 
from . import abc 

# ... 
__all__ = list_of_names_to_export + abc.__all__ 

अपने __init__.py अंदर।


वास्तविक इस्तेमाल किया कार्यान्वयन सी तथापि में है: _collectionsmodule.c

+0

एक .abc पैकेज मेरे उद्देश्यों के लिए एक उपयुक्त समाधान प्रतीत होता है। धन्यवाद! –

0

यह वास्तव में एक विशिष्ट मॉड्यूल आरंभीकरण के लिए __init__.py उपयोग करना संभव है, लेकिन मैंने कभी भी नए कार्यों को परिभाषित करने के लिए इसका उपयोग नहीं किया है। मुझे पता है कि केवल "सही" उपयोग this subject ... में चर्चा की गई है।

वैसे भी, जैसा कि आपके पास एक जटिल अनुप्रयोग हो सकता है, आप एक अस्थायी फ़ाइल का उपयोग कर सकते हैं जहां आप __init__.py मॉड्यूल में उन्हें सीधे परिभाषित करने के बजाय अपने सभी आवश्यक कार्यों को परिभाषित करते हैं। यह आपको और अधिक पठनीयता की अनुमति देगा, बाद में इसे बदलना आसान है।

+0

_temporary_ _file_ द्वारा आपका क्या मतलब है? मैं '__init __। Py' में कच्चे कार्यों को परिभाषित नहीं कर रहा हूं। मैं संबंधित पैकेजों के उप-पैकेज और मॉड्यूल में अन्य वर्गों द्वारा विस्तारित होने के लिए जेनेरिक _classes_ को परिभाषित कर रहा हूं। –

0

नहीं कभी उपयोग __init__.py करो __all__ को परिभाषित करने के अलावा कुछ के लिए। यदि आप इससे बचेंगे तो आप इतने सारे जीवन बचाएंगे।

कारण: डेवलपर्स के लिए पैकेज और मॉड्यूल को देखना आम बात है। लेकिन एक समस्या है जिसे आप कभी-कभी अटक सकते हैं। यदि आपके पास पैकेज है, तो आप मानते हैं कि इसके अंदर एक मॉड्यूल और कोड है। लेकिन आप शायद ही कभी __init__.py को एक के रूप में गिनेंगे, क्योंकि, इसका सामना करते हैं, ज्यादातर बार यह निर्देशिका आयात करने योग्य मॉड्यूल बनाने की आवश्यकता होती है।

package 
    __init__.py 
    mod1.py 
    humans.py 
    cats.py 
    dogs.py 
    cars.py 
    commons.py 

कक्षा Family कहां स्थित होना चाहिए? यह सामान्य वर्ग है और यह दूसरों पर निर्भर करता है, क्योंकि हम मनुष्यों, कुत्तों और बिल्लियों, यहां तक ​​कि कारों का परिवार भी बना सकते हैं!

मेरे तर्क और मेरे दोस्तों के तर्क से, यह अलग फ़ाइल में जगह होनी चाहिए, लेकिन मैं commons में इसे humans में ढूंढने की कोशिश करूंगा और फिर ... मैं शर्मिंदा हूं, क्योंकि मैं शर्मिंदा नहीं हूं वास्तव में पता है कि यह कहां है!

बेवकूफ उदाहरण, हुह? लेकिन यह एक बिंदु देता है।

+0

** ** ** ** अधिक * पूरी तरह से * कानूनी उपयोग हैं। दो सरल उदाहरण: मॉड्यूल लोड करना जो ओएस विशिष्ट हैं। आमतौर पर प्रयुक्त वस्तुओं को प्रदान करना जो submodules में निर्धारित हैं। – Bakuriu

+0

हाँ, मेरा मतलब है "परिभाषित करना '__all__'" - बस मॉड्यूल लोड करना और प्रदान करना। – dt0xff

3

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

मॉड्यूल के अंदर या पैकेज के अंदर समान नियम लागू करना चाहिए। मैं Bakuriu से सहमत हूं कि __init__.py पैकेज आधारभूत संरचना से निकटता से संबंधित होना चाहिए, लेकिन मॉड्यूल की कार्यक्षमता के लिए असफल नहीं है। मेरी व्यक्तिगत राय यह है कि __init__.py जितना संभव हो उतना सरल होना चाहिए। कारण सबसे पहले यह है कि सबकुछ जितना संभव हो उतना सरल होना चाहिए, लेकिन आसान नहीं होना चाहिए। दूसरा, आपके पैकेज के कोड को पढ़ने वाले लोग इस तरह सोचते हैं। वे __init__.py में अप्रत्याशित कार्यक्षमता की अपेक्षा नहीं कर सकते हैं। उद्देश्य के लिए पैकेज के अंदर generic.py बनाना शायद बेहतर होगा। मॉड्यूल के उद्देश्य को दस्तावेज करना आसान है (इसके शीर्ष डॉकस्ट्रिंग के माध्यम से कहें)।

बेहतर अलगाव शुरुआत से ही बेहतर है, बेहतर सुविधाओं को भविष्य में संयुक्त किया जा सकता है। पैकेज के अंदर मॉड्यूल के उपयोग के लिए और भविष्य में संशोधनों के लिए दोनों को बेहतर लचीलापन मिलता है।

+0

धन्यवाद! इससे मुझे बहुत मदद मिलती है। –

संबंधित मुद्दे