क्या पायथन में एक ही फ़ाइल में कई कक्षाएं होना ठीक है?


18

मैं जावा और पीएचपी के वर्षों के बाद नए सिरे से पायथन दुनिया में आ रहा हूं। हालांकि भाषा अपने आप में बहुत सीधी है, मैं कुछ ऐसे 'छोटे' मुद्दों से जूझ रहा हूं जिन्हें मैं अपने सिर के चारों ओर लपेट नहीं सकता हूं - और जिनके बारे में मैंने अब तक पढ़े कई दस्तावेजों और ट्यूटोरियल में जवाब नहीं मिल सका है। ।

अनुभवी पायथन व्यवसायी के लिए, यह प्रश्न मूर्खतापूर्ण लग सकता है, लेकिन मैं वास्तव में इसका उत्तर चाहता हूं ताकि मैं भाषा के लिए आगे जा सकूं:

जावा और पीएचपी ( हालाँकि इसकी सख्ती से आवश्यकता नहीं है ) में, आपसे अपेक्षा की जाती है कि आप classइसकी प्रत्येक फ़ाइल पर लिखें , जिसमें फ़ाइल का नाम classएक सर्वोत्तम अभ्यास है।

लेकिन पायथन में, या कम से कम मैंने जिन ट्यूटोरियल्स में जाँच की है, उनमें एक ही फाइल में कई कक्षाएं होना ठीक है।

क्या यह नियम उत्पादन, तैनाती-तैयार कोड में है या यह केवल शिक्षाप्रद-केवल कोड में संक्षिप्तता के लिए किया गया है?

जवाबों:


13

क्या पायथन में एक ही फ़ाइल में कई कक्षाएं होना ठीक है?

हाँ। दोनों दार्शनिक दृष्टिकोण से और साथ ही व्यावहारिक भी।

पायथन में, मॉड्यूल एक नाम स्थान है जो एक बार स्मृति में मौजूद हैं।

मान लें कि हमारे पास निम्न काल्पनिक निर्देशिका संरचना है, जिसमें प्रति फ़ाइल एक वर्ग परिभाषित है:

                    Defines
 abc/
 |-- callable.py    Callable
 |-- container.py   Container
 |-- hashable.py    Hashable
 |-- iterable.py    Iterable
 |-- iterator.py    Iterator
 |-- sized.py       Sized
 ... 19 more

ये सभी कक्षाएं collectionsमॉड्यूल में उपलब्ध हैं और (वास्तव में, कुल मिलाकर 25) मानक पुस्तकालय मॉड्यूल में परिभाषित हैं_collections_abc.py

यहाँ कुछ मुद्दे हैं जो मेरा मानना ​​है _collections_abc.pyकि वैकल्पिक काल्पनिक निर्देशिका संरचना से बेहतर है।

  • इन फ़ाइलों को वर्णानुक्रम में क्रमबद्ध किया जाता है। आप उन्हें अन्य तरीकों से सॉर्ट कर सकते हैं, लेकिन मुझे एक ऐसी सुविधा के बारे में पता नहीं है, जो सिमेंटिक डिपेंडेंसी द्वारा फाइलों को सॉर्ट करती है। _Collections_abc मॉड्यूल स्रोत निर्भरता द्वारा आयोजित किया जाता है।
  • गैर-पैथोलॉजिकल मामलों में, मॉड्यूल और क्लास परिभाषा दोनों एकल हैं, स्मृति में एक बार होने वाली। कक्षाओं में मॉड्यूल की एक विशेषण मानचित्रण होगा - मॉड्यूल को निरर्थक बना देगा।
  • फ़ाइलों की बढ़ती संख्या कक्षाओं के माध्यम से आकस्मिक रूप से पढ़ने के लिए कम सुविधाजनक बनाती है (जब तक कि आपके पास आईडीई नहीं है जो इसे सरल बनाता है) - यह बिना उपकरण के लोगों के लिए कम सुलभ बनाता है।

क्या आप अलग-अलग मॉड्यूल में कक्षाओं के समूहों को तोड़ने से रोकते हैं जब आप इसे नाम स्थान और संगठनात्मक दृष्टिकोण से वांछनीय पाते हैं?

नहीं।

पायथन के ज़ेन से , जो उस दर्शन और सिद्धांतों को दर्शाता है जिसके तहत यह विकसित हुआ और विकसित हुआ:

नाम स्थान एक महान विचार का सम्मान कर रहे हैं - चलो उन में से अधिक करते हैं!

लेकिन हम ध्यान रखें कि यह भी कहता है:

फ्लैट नेस्टेड से बेहतर है।

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

यहाँ सार आधार वर्ग मॉड्यूल से वास्तविक कोड है । मैं इसे भाषा में विभिन्न अमूर्त प्रकारों के निरूपण के लिए एक संदर्भ के रूप में उपयोग करना पसंद करता हूं।

क्या आप कहेंगे कि इनमें से प्रत्येक वर्ग को एक अलग फाइल की आवश्यकता होगी?

class Hashable:
    __metaclass__ = ABCMeta

    @abstractmethod
    def __hash__(self):
        return 0

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Hashable:
            try:
                for B in C.__mro__:
                    if "__hash__" in B.__dict__:
                        if B.__dict__["__hash__"]:
                            return True
                        break
            except AttributeError:
                # Old-style class
                if getattr(C, "__hash__", None):
                    return True
        return NotImplemented


class Iterable:
    __metaclass__ = ABCMeta

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterable:
            if _hasattr(C, "__iter__"):
                return True
        return NotImplemented

Iterable.register(str)


class Iterator(Iterable):

    @abstractmethod
    def next(self):
        'Return the next item from the iterator. When exhausted, raise StopIteration'
        raise StopIteration

    def __iter__(self):
        return self

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterator:
            if _hasattr(C, "next") and _hasattr(C, "__iter__"):
                return True
        return NotImplemented


class Sized:
    __metaclass__ = ABCMeta

    @abstractmethod
    def __len__(self):
        return 0

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Sized:
            if _hasattr(C, "__len__"):
                return True
        return NotImplemented


class Container:
    __metaclass__ = ABCMeta

    @abstractmethod
    def __contains__(self, x):
        return False

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Container:
            if _hasattr(C, "__contains__"):
                return True
        return NotImplemented


class Callable:
    __metaclass__ = ABCMeta

    @abstractmethod
    def __call__(self, *args, **kwds):
        return False

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Callable:
            if _hasattr(C, "__call__"):
                return True
        return NotImplemented

तो क्या वे प्रत्येक की अपनी फ़ाइल होनी चाहिए?

मुझे आशा नहीं है।

ये फाइलें सिर्फ कोड नहीं हैं - वे पायथन के शब्दार्थ पर दस्तावेज हैं।

वे शायद औसतन 10 से 20 लाइनें हैं। कोड की एक और 10 लाइनों को देखने के लिए मुझे पूरी तरह से अलग फ़ाइल पर क्यों जाना चाहिए? यह बहुत अव्यवहारिक होगा। इसके अलावा, कोड की अधिक अनावश्यक लाइनों को जोड़ते हुए, प्रत्येक फ़ाइल पर लगभग समान बॉयलरप्लेट आयात होगा।

मुझे यह जानना काफी उपयोगी है कि एक एकल मॉड्यूल है जहां मैं इन सभी सार बेस कक्षाओं को पा सकता हूं, बजाय इसके कि मॉड्यूल की सूची पर ध्यान दिया जाए। उन्हें एक-दूसरे के संदर्भ में देखने से मुझे उन्हें बेहतर ढंग से समझने में मदद मिलती है। जब मैं देखता हूं कि एक Iterator एक Iterable है, तो मैं जल्दी से समीक्षा कर सकता हूं कि एक Iterable में क्या होता है।

मैं कभी-कभी बहुत कम कक्षाओं के एक जोड़े को हवा देता हूं। वे फ़ाइल में बने रहते हैं, भले ही उन्हें समय के साथ बड़ा होने की आवश्यकता हो। कभी-कभी परिपक्व मॉड्यूल में 1000 से अधिक लाइनें होती हैं। लेकिन ctrl-f आसान है, और कुछ IDE फ़ाइल की रूपरेखा को देखना आसान बनाते हैं - इसलिए फ़ाइल चाहे कितनी भी बड़ी हो, आप जिस भी वस्तु या विधि की तलाश कर रहे हैं, आप जल्दी जा सकते हैं।

निष्कर्ष

मेरी दिशा, पायथन के संदर्भ में, एक ही फाइल में संबंधित और शब्दार्थ समान श्रेणी की परिभाषाएं रखना पसंद करती है। यदि फ़ाइल इतनी बड़ी हो जाती है कि वह बहुत बड़ी हो जाती है, तो एक पुनर्गठन पर विचार करें।


1
ठीक है, जबकि मैं समझता हूं, आपके द्वारा प्रस्तुत कोड के लिए धन्यवाद कि एक ही फ़ाइल में कई कक्षाएं होना ठीक है, मैं तर्क को बहुत आश्वस्त नहीं कर सकता। उदाहरण के लिए, PHP में यह पूरी तरह से समान कोड वाली पूरी फ़ाइल होना आम बात थी:class SomeException extends \Exception {}
ओलिवियर मल्की

3
विभिन्न समुदायों में अलग-अलग कोडिंग मानक हैं। जावा के लोग अजगर को देखते हैं और कहते हैं कि "यह प्रति फ़ाइल कई वर्गों की अनुमति क्यों देता है!"। अजगर लोग जावा को देखते हैं और कहते हैं कि "प्रत्येक वर्ग की अपनी फ़ाइल की आवश्यकता क्यों है?"। यह समुदाय आप में काम कर रहे हैं की शैली का अनुसरण करने के लिए सबसे अच्छा है।
Gort रोबोट

मैं यहाँ भी भ्रमित हूँ। जाहिर तौर पर मैंने अपने जवाब से पायथन के बारे में कुछ बातों को गलत समझा। लेकिन क्या एक वर्ग के लिए संभव के रूप में कई तरीकों को जोड़ने के लिए "फ्लैट नेस्टेड से बेहतर है" लागू होगा? सामान्य तौर पर मुझे लगता है कि सामंजस्य और एसआरपी के सिद्धांत अभी भी एक मॉड्यूल के अनुकूल मॉड्यूल पर लागू होते हैं जो उन कक्षाओं को प्रदान करते हैं जो कार्यक्षमता में एक दूसरे से निकटता से संबंधित हैं (हालांकि एक मॉड्यूल से बहुत अच्छी तरह से एक वर्ग से अधिक एक एकल वर्ग की तुलना में एक मोटे पैकेज अवधारणा मॉडल ), विशेष रूप से चूंकि किसी भी मॉड्यूल-स्कोप वैरिएबल (हालांकि सामान्य रूप से उम्मीद से बचा जाता है) के दायरे में वृद्धि होगी।

1
पायथन का ज़ेन उन सिद्धांतों की एक सूची है जो एक दूसरे के साथ तनाव में हैं। आपकी बात के साथ एक समझौते का जवाब हो सकता है, "स्पार्स घने से बेहतर है।" - जो तुरंत अनुसरण करता है, "फ्लैट नेस्टेड से बेहतर है।" द ज़ेन ऑफ़ पाइथन की व्यक्तिगत लाइनों का आसानी से दुरुपयोग किया जा सकता है और चरम सीमा पर ले जाया जा सकता है, लेकिन समग्र रूप से लिया जाए तो यह कोडिंग की कला में मदद कर सकता है और आम ज़मीन खोज सकता है जहाँ उचित लोग अन्यथा असहमत हो सकते हैं। मुझे नहीं लगता कि लोग मेरे कोड उदाहरणों पर विचार करेंगे, लेकिन आप जो वर्णन करते हैं, वह मुझे बहुत घना लगता है।
हारून हॉल

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

4

पायथन में अपने एप्लिकेशन को संरचित करते समय, आपको पैकेज और मॉड्यूल के संदर्भ में सोचने की जरूरत है।

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

इंडेक्स ऑफ पाइथन एनहांसमेंट प्रपोजल के बारे में समय-समय पर पढ़ना न भूलें ।


2

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

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

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


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