পাইথনের অভ্যন্তর শ্রেণীর উদ্দেশ্য কী?


100

পাইথনের অভ্যন্তরীণ / নেস্টেড ক্লাসগুলি আমাকে বিভ্রান্ত করে। এমন কিছু আছে যা এগুলি ছাড়া সম্পন্ন করা যায় না? যদি তা হয় তবে সে জিনিসটি কী?

উত্তর:


89

Http://www.geekinterview.com/question_details/64739 থেকে উদ্ধৃত :

অভ্যন্তর শ্রেণীর সুবিধা:

  • ক্লাসগুলির যৌক্তিক গোষ্ঠীকরণ : কোনও শ্রেণি যদি কেবলমাত্র অন্য একটি শ্রেণির জন্য কার্যকর হয় তবে সেটিকে এই শ্রেণিতে এম্বেড করা এবং দুটিকে একসাথে রাখা যুক্তিযুক্ত। এই জাতীয় "সহায়ক শ্রেণি" বাসা বাঁধাই তাদের প্যাকেজটিকে আরও সুচলিত করে তোলে।
  • বর্ধিত এনক্যাপসুলেশন : এ এবং বি দুটি শীর্ষ স্তরের শ্রেণীর বিবেচনা করুন যেখানে খ এর এ সদস্যদের অ্যাক্সেস প্রয়োজন যা অন্যথায় ব্যক্তিগত হিসাবে ঘোষণা করা হবে। ক্লাস বি ক্লাসের মধ্যে লুকিয়ে রাখার মাধ্যমে এএ এর সদস্যদের ব্যক্তিগত হিসাবে ঘোষণা করা যেতে পারে এবং বি তাদের অ্যাক্সেস করতে পারে। এ ছাড়া খ নিজেই বাইরের বিশ্ব থেকে লুকিয়ে থাকতে পারে।
  • আরও পঠনযোগ্য, রক্ষণাবেক্ষণযোগ্য কোড : শীর্ষ স্তরের শ্রেণির মধ্যে ছোট ক্লাসগুলিতে বাসা বাঁধাই কোডটি যেখানে ব্যবহৃত হয় তার কাছাকাছি রাখে।

মূল সুবিধা হ'ল সংগঠন। কিছু যে ভেতরের শ্রেণীর সহযোগে এটি করা যাবে পারেন তাদের ছাড়া শেষ হবে না।


50
অবশ্যই এনক্যাপসুলেশন আর্গুমেন্ট পাইথনের ক্ষেত্রে প্রযোজ্য নয়।
বোবিনস

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

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

16
@ ইনভারসাস: আমি একমত নই এটি কোনও উত্তর নয়, এটি ভিন্ন ভাষার (যথা জাভা) সম্পর্কে অন্য কারও উত্তর থেকে বর্ধিত উদ্ধৃতি । ডাউনভোটেড এবং আমি আশা করি অন্যরাও এটি করবে।
কেভিন

5
আমি এই উত্তরের সাথে একমত এবং আপত্তিগুলির সাথে একমত নই। যদিও নেস্টেড ক্লাসগুলি জাভার অভ্যন্তরীণ ক্লাস নয় তবে সেগুলি কার্যকর। নেস্টেড ক্লাসের উদ্দেশ্য সংগঠন। কার্যকরভাবে, আপনি অন্য শ্রেণীর নাম স্থানের নীচে একটি শ্রেণি স্থাপন করছেন। যখন এটি করার পক্ষে যৌক্তিক ধারণা তৈরি হয়, এটি পাইথোনিক: "নেমস্পেসগুলি হ'ল এক দুর্দান্ত ধারণা - এর আসুন আরও কিছু করা যাক!"! উদাহরণস্বরূপ, একটি DataLoaderশ্রেণি বিবেচনা করুন যা একটি CacheMissব্যতিক্রম ছুঁড়ে ফেলতে পারে । মূল শ্রেণীর অধীনে ব্যতিক্রমকে বাসা বেঁধে নেওয়ার DataLoader.CacheMissঅর্থ আপনি কেবল আমদানি করতে পারেন DataLoaderতবে এখনও ব্যতিক্রমটি ব্যবহার করতে পারেন।
সিবারিক 4

50

এমন কিছু আছে যা এগুলি ছাড়া সম্পন্ন করা যায় না?

না। তারা শীর্ষ স্তরে সাধারণত শ্রেণিটি সংজ্ঞায়িত করার এবং তারপরে একটি রেফারেন্সটি বাইরের শ্রেণিতে অনুলিপি করার পক্ষে একেবারে সমান।

আমি মনে করি না যে নেস্টেড ক্লাসগুলিকে 'অনুমোদিত' করার কোনও বিশেষ কারণ রয়েছে, অন্যথায় এগুলি পরিষ্কারভাবে 'অস্বীকার' করার কোনও বিশেষ ধারণা নেই।

আপনি যদি কোনও শ্রেণীর সন্ধান করছেন যা বাহ্যিক / মালিকের অবজেক্টের জীবনচক্রের মধ্যে বিদ্যমান এবং সর্বদা বাহ্যিক শ্রেণীর কোনও উদাহরণ - জাভা যেমন অভ্যন্তরীণ শ্রেণিগুলির জন্য উল্লেখ করে - তবে পাইথনের নেস্টেড ক্লাসগুলি সেই জিনিস নয়। তবে আপনি সেই জিনিসটির মতো কিছু হ্যাক করতে পারেন :

import weakref, new

class innerclass(object):
    """Descriptor for making inner classes.

    Adds a property 'owner' to the inner class, pointing to the outer
    owner instance.
    """

    # Use a weakref dict to memoise previous results so that
    # instance.Inner() always returns the same inner classobj.
    #
    def __init__(self, inner):
        self.inner= inner
        self.instances= weakref.WeakKeyDictionary()

    # Not thread-safe - consider adding a lock.
    #
    def __get__(self, instance, _):
        if instance is None:
            return self.inner
        if instance not in self.instances:
            self.instances[instance]= new.classobj(
                self.inner.__name__, (self.inner,), {'owner': instance}
            )
        return self.instances[instance]


# Using an inner class
#
class Outer(object):
    @innerclass
    class Inner(object):
        def __repr__(self):
            return '<%s.%s inner object of %r>' % (
                self.owner.__class__.__name__,
                self.__class__.__name__,
                self.owner
            )

>>> o1= Outer()
>>> o2= Outer()
>>> i1= o1.Inner()
>>> i1
<Outer.Inner inner object of <__main__.Outer object at 0x7fb2cd62de90>>
>>> isinstance(i1, Outer.Inner)
True
>>> isinstance(i1, o1.Inner)
True
>>> isinstance(i1, o2.Inner)
False

(এটি ক্লাস সাজসজ্জা ব্যবহার করে, যা পাইথন ২.6 এবং in.০ এ নতুন Otherwise


5
ব্যবহার-মামলা যে জন্য কল যে (অর্থাত জাভা এসকিউ ভেতরের ক্লাস, যার দৃষ্টান্ত বাইরের ক্লাসের দৃষ্টান্ত সঙ্গে একটি সম্পর্ক আছে) সাধারণত ভিতরে ভিতরের বর্গ নির্ধারণ করে পাইথন সুরাহা করা যেতে পারে পদ্ধতি বাইরের ক্লাসের - তারা দেখতে হবে selfকোনও অতিরিক্ত কাজ ছাড়াই বাহ্যিকের প্রয়োজন (কেবলমাত্র একটি আলাদা শনাক্তকারী ব্যবহার করুন যেখানে আপনি সাধারণত অভ্যন্তরীণটি selfরাখবেন; যেমন innerself) এবং এর মাধ্যমে বাইরের উদাহরণটি অ্যাক্সেস করতে সক্ষম হবেন।
এভেজেনি সার্জিভ

WeakKeyDictionaryএই উদাহরণটিতে একটি ব্যবহার করে কীগুলি আসলে আবর্জনা সংগ্রহের অনুমতি দেয় না, কারণ মানগুলি তাদের গুনের মাধ্যমে তাদের নিজ নিজ কীগুলি দৃ strongly়ভাবে উল্লেখ করে owner
ক্রিজেফিটজ

36

এটি বুঝতে সক্ষম হওয়ার জন্য আপনার মাথাটি প্রায় জড়িয়ে রাখতে হবে। বেশিরভাগ ভাষায় ক্লাস সংজ্ঞা সংকলককে নির্দেশ দেয়। অর্থাৎ প্রোগ্রামটি কখনও চালিত হওয়ার আগে ক্লাস তৈরি করা হয়। পাইথনে, সমস্ত বিবৃতি কার্যকর হয়। তার অর্থ এই বিবৃতি:

class foo(object):
    pass

এটি একটি বিবৃতি যা রানটাইমের সময় ঠিক এই মত কার্যকর করা হয়:

x = y + z

এর অর্থ হল যে আপনি কেবল অন্যান্য ক্লাসের মধ্যেই ক্লাস তৈরি করতে পারবেন না, আপনি যে কোনও জায়গায় ক্লাস তৈরি করতে পারবেন। এই কোডটি বিবেচনা করুন:

def foo():
    class bar(object):
        ...
    z = bar()

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


16

ক্লাসের মধ্যে নেস্টিং ক্লাস:

  • নেস্টেড ক্লাসগুলি ক্লাস সংজ্ঞাটি ফুলেছে যা ঘটছে তা দেখা শক্ত করে তোলে।

  • নেস্টেড ক্লাসগুলি সংযোজন তৈরি করতে পারে যা পরীক্ষা আরও কঠিন করে তুলবে।

  • পাইথনে আপনি জাভা থেকে আলাদা কোনও ফাইল / মডিউলে একাধিক ক্লাস রাখতে পারেন, সুতরাং ক্লাসটি এখনও শীর্ষ স্তরের শ্রেণির কাছাকাছি থাকে এবং ক্লাসের নামটি "_" দিয়ে উপস্থাপিত করতে পারে যাতে অন্যকে না হওয়া উচিত এটি ব্যবহার করছি.

জায়গা যেখানে নেস্টেড ক্লাসগুলি কার্যকর প্রমাণ করতে পারে তা হ'ল ফাংশনগুলির মধ্যে

def some_func(a, b, c):
   class SomeClass(a):
      def some_method(self):
         return b
   SomeClass.__doc__ = c
   return SomeClass

ক্লাসটি আপনাকে ক্রিয়াকলাপে সি ++ তে টেমপ্লেট মেটাপোগ্র্যামিংয়ের মতো শ্রেণি তৈরি করার অনুমতি দেয় ফাংশন থেকে মানগুলি ক্যাপচার করে


7

আমি নেস্টেড ক্লাসগুলির বিরুদ্ধে যুক্তিগুলি বুঝতে পারি, তবে কয়েকটি অনুষ্ঠানে সেগুলি ব্যবহারের জন্য একটি মামলা রয়েছে। কল্পনা করুন যে আমি দ্বিগুণ-সংযুক্ত তালিকার শ্রেণি তৈরি করছি এবং নোডগুলি রক্ষণাবেক্ষণের জন্য আমার নোড শ্রেণি তৈরি করা দরকার। আমার দুটি পছন্দ আছে, ডাবলিংকডলিস্ট ক্লাসের ভিতরে নোড ক্লাস তৈরি করুন, বা ডাবলিংকডলিস্ট ক্লাসের বাইরে নোড ক্লাস তৈরি করুন। আমি এই ক্ষেত্রে প্রথম পছন্দটি পছন্দ করি, কারণ নোড ক্লাস কেবলমাত্র ডাবললিঙ্কডলিস্ট শ্রেণীর মধ্যে অর্থবোধক। যদিও কোনও আড়াল / এনক্যাপসুলেশন সুবিধা নেই, নোড ক্লাসটি ডাবলিংকডলিস্ট শ্রেণীর একটি অংশ বলে বলতে সক্ষম হওয়ার একটি গ্রুপিং সুবিধা রয়েছে।


5
এটি সত্য যে ধরে নেওয়া যায় যে একই Nodeশ্রেণিটি অন্যান্য ধরণের লিঙ্কযুক্ত তালিকার শ্রেণীর জন্যও কার্যকর নয় যা আপনিও তৈরি করতে পারেন, সেক্ষেত্রে সম্ভবত এটি কেবল বাইরে থাকা উচিত।
একিউম্যানাস

এটি রাখার আরেকটি উপায়: Nodeএর নেমস্পেসের অধীনে DoublyLinkedListএবং এটি যুক্তিযুক্ত বোধ তৈরি করে। এই হল Pythonic: "নামস্থান এক মহান ধারণা honking রয়েছে - আসুন যারা আরও অনেক কিছু!"
সিবারিক 3

@ কেবারিক: "আরও অনেকগুলি" করা তাদের বাসা বাঁধার বিষয়ে কিছুই বলে না says
ইথান ফুরম্যান

4

এমন কিছু আছে যা এগুলি ছাড়া সম্পন্ন করা যায় না? যদি তা হয় তবে সে জিনিসটি কী?

এমন কিছু রয়েছে যা সহজেই করা যায় না : সম্পর্কিত শ্রেণীর উত্তরাধিকার

এখানে এর সাথে সম্পর্কিত শ্রেণীর সঙ্গে একটি সংক্ষিপ্ত সংযুক্তি উদাহরণ Aএবং B:

class A(object):
    class B(object):
        def __init__(self, parent):
            self.parent = parent

    def make_B(self):
        return self.B(self)


class AA(A):  # Inheritance
    class B(A.B):  # Inheritance, same class name
        pass

এই কোডটি বেশ যুক্তিসঙ্গত এবং অনুমানযোগ্য আচরণের দিকে পরিচালিত করে:

>>> type(A().make_B())
<class '__main__.A.B'>
>>> type(A().make_B().parent)
<class '__main__.A'>
>>> type(AA().make_B())
<class '__main__.AA.B'>
>>> type(AA().make_B().parent)
<class '__main__.AA'>

যদি Bশীর্ষ-স্তরের শ্রেণি থাকে তবে আপনি self.B()পদ্ধতিতে লিখতে না পারলেও make_Bকেবল লিখতে পারতেন B()এবং এভাবে পর্যাপ্ত শ্রেণীর গতিশীল বাঁধাই হারাতেন ।

নোট করুন যে এই নির্মাণে, আপনার কখনই বর্গের Aবডিতে ক্লাস উল্লেখ করা উচিত নয় B। এটি parentক্লাসে বৈশিষ্ট্যটি প্রবর্তনের জন্য অনুপ্রেরণা B

অবশ্যই, ক্লাসগুলির এক ক্লান্তিকর এবং ত্রুটি-প্রবণ উপকরণের দামের ভিত্তিতে এই গতিশীল বাইন্ডিংটি অভ্যন্তর শ্রেণি ছাড়াই পুনরায় তৈরি করা যেতে পারে ।


1

আমি এটির জন্য প্রধান ব্যবহারের ক্ষেত্রে ব্যবহার করছি ছোট মডিউলগুলির বিস্তার রোধ করা এবং যখন পৃথক মডিউলগুলির প্রয়োজন হয় না তখন নেমস্পেস দূষণ রোধ করা। যদি আমি একটি বিদ্যমান শ্রেণি প্রসারিত করি তবে তবে বিদ্যমান বর্গটিকে অবশ্যই অন্য সাবক্লাসটি উল্লেখ করতে হবে যা সর্বদা এর সাথে মিলিত হওয়া উচিত led উদাহরণস্বরূপ, আমি একটি থাকতে পারে utils.pyমডিউল যে অগত্যা একসঙ্গে মিলিত হয় না এটা অনেক সাহায্যকারী ক্লাস, আছে, কিন্তু আমি এর জন্য সংযোজন পুনরায় বলবৎ করতে চান কিছু ঐ সাহায্যকারী ক্লাস। উদাহরণস্বরূপ, আমি যখন https://stackoverflow.com/a/8274307/2718295 প্রয়োগ করি

: utils.py:

import json, decimal

class Helper1(object):
    pass

class Helper2(object):
    pass

# Here is the notorious JSONEncoder extension to serialize Decimals to JSON floats
class DecimalJSONEncoder(json.JSONEncoder):

    class _repr_decimal(float): # Because float.__repr__ cannot be monkey patched
        def __init__(self, obj):
            self._obj = obj
        def __repr__(self):
            return '{:f}'.format(self._obj)

    def default(self, obj): # override JSONEncoder.default
        if isinstance(obj, decimal.Decimal):
            return self._repr_decimal(obj)
        # else
        super(self.__class__, self).default(obj)
        # could also have inherited from object and used return json.JSONEncoder.default(self, obj) 

তাহলে আমরা পারবো:

>>> from utils import DecimalJSONEncoder
>>> import json, decimal
>>> json.dumps({'key1': decimal.Decimal('1.12345678901234'), 
... 'key2':'strKey2Value'}, cls=DecimalJSONEncoder)
{"key2": "key2_value", "key_1": 1.12345678901234}

অবশ্যই, আমরা json.JSONEnocderপুরোপুরি উত্তরাধিকার সূচনা করতে পেরেছি এবং কেবল ডিফল্ট () কে ওভাররাইড করতে পারি :

:

import decimal, json

class Helper1(object):
    pass

def json_encoder_decimal(obj):
    class _repr_decimal(float):
        ...

    if isinstance(obj, decimal.Decimal):
        return _repr_decimal(obj)

    return json.JSONEncoder(obj)


>>> json.dumps({'key1': decimal.Decimal('1.12345678901234')}, default=json_decimal_encoder)
'{"key1": 1.12345678901234}'

তবে কখনও কখনও কেবল সম্মেলনের জন্য, আপনি utilsএক্সটেনসিবিলিটির জন্য ক্লাসের সমন্বয়ে গঠিত হতে চান ।

এখানে অন্য ব্যবহারের ক্ষেত্রে: আমি আমার আউটারক্লাসে পরিবর্তনের জন্য কারখানা চাই না copy:

class OuterClass(object):

    class DTemplate(dict):
        def __init__(self):
            self.update({'key1': [1,2,3],
                'key2': {'subkey': [4,5,6]})


    def __init__(self):
        self.outerclass_dict = {
            'outerkey1': self.DTemplate(),
            'outerkey2': self.DTemplate()}



obj = OuterClass()
obj.outerclass_dict['outerkey1']['key2']['subkey'].append(4)
assert obj.outerclass_dict['outerkey2']['key2']['subkey'] == [4,5,6]

আমি ডেকরেটারের তুলনায় এই প্যাটার্নটি পছন্দ করি @staticmethodআপনি অন্যথায় কোনও কারখানা ফাংশনের জন্য ব্যবহার করবেন।


1

1. দুটি কার্যকরী সমতুল্য উপায়

সামনে দেখানো দুটি উপায় আছে বৈশিষ্ট্যগুলি অভিন্ন। তবে কিছু সূক্ষ্ম পার্থক্য রয়েছে এবং এমন পরিস্থিতি রয়েছে যখন আপনি একে অপরকে বেছে নিতে চান to

ওয়ে 1: নেস্টেড বর্গ সংজ্ঞা
(= "নেস্টেড ক্লাস")

class MyOuter1:
    class Inner:
        def show(self, msg):
            print(msg)

উপায় 2: মডিউল স্তরের অভ্যন্তর শ্রেণীর সাথে বহিরাগত শ্রেণীর সাথে সংযুক্ত
(= "রেফারেন্সড ইনার ক্লাস")

class _InnerClass:
    def show(self, msg):
        print(msg)

class MyOuter2:
    Inner = _InnerClass

ইনডকোয়ার পিইপি 8 "অভ্যন্তরীণ ইন্টারফেস (প্যাকেজ, মডিউল, শ্রেণি, ফাংশন, বৈশিষ্ট্য বা অন্যান্য নাম) অনুসরণ করতে ব্যবহার করা উচিত - একক শীর্ষস্থানীয় আন্ডারস্কোর সহ উপসর্গ করা উচিত" "

2. মিল

নীচে কোড স্নিপেট "নেস্টেড ক্লাস" বনাম "রেফারেন্সড ইনার ক্লাস" এর ক্রিয়ামূলক মিল দেখায়; কোনও অভ্যন্তরীণ শ্রেণীর উদাহরণের ধরণের কোড কোড পরীক্ষায় তারা একই আচরণ করবে। বলা বাহুল্য, এর m.inner.anymethod()সাথে m1এবং একইরকম আচরণ করবেm2

m1 = MyOuter1()
m2 = MyOuter2()

innercls1 = getattr(m1, 'Inner', None)
innercls2 = getattr(m2, 'Inner', None)

isinstance(innercls1(), MyOuter1.Inner)
# True

isinstance(innercls2(), MyOuter2.Inner)
# True

type(innercls1()) == mypackage.outer1.MyOuter1.Inner
# True (when part of mypackage)

type(innercls2()) == mypackage.outer2.MyOuter2.Inner
# True (when part of mypackage)

3. পার্থক্য

"নেস্টেড বর্গ" এবং "রেফারেন্সড ইনার ক্লাস" এর পার্থক্য নীচে তালিকাভুক্ত করা হয়েছে। এগুলি বড় নয় তবে কখনও কখনও আপনি এগুলির উপর ভিত্তি করে একটি বা অন্যটি চয়ন করতে চান।

৩.১ কোড এনক্যাপসুলেশন

"নেস্টেড ক্লাসগুলি" দিয়ে "রেফারেন্সড ইনার ক্লাস" এর চেয়ে ভাল কোড এনক্যাপুলেট করা সম্ভব। মডিউল নেমস্পেসের একটি শ্রেণি একটি বৈশ্বিক চলক। নেস্টেড ক্লাসগুলির উদ্দেশ্য হ'ল মডিউলটিতে বিশৃঙ্খলা হ্রাস করা এবং অভ্যন্তরীণ শ্রেণিকে বাইরের শ্রেণীর ভিতরে রাখা।

যখন কোনও * ব্যবহার করছে না from packagename import *, কোড সমাপ্তি / ইন্টেলিসেন্স সহ আইডিই ব্যবহার করার সময় উদাহরণস্বরূপ কম পরিমাণে মডিউল স্তরের ভেরিয়েবলগুলি দুর্দান্ত হতে পারে।

* ঠিক?

৩.২ কোডের পাঠযোগ্যতা

জ্যাঙ্গো ডকুমেন্টেশন মডেল মেটাডেটার জন্য অভ্যন্তর শ্রেণীর মেটা ব্যবহার করার নির্দেশ দেয় । ফ্রেমওয়ার্ক ব্যবহারকারীদের class Foo(models.Model)অভ্যন্তর দিয়ে একটি লেখার নির্দেশ দেওয়া আরও কিছুটা পরিষ্কার * class Meta;

class Ox(models.Model):
    horn_length = models.IntegerField()

    class Meta:
        ordering = ["horn_length"]
        verbose_name_plural = "oxen"

পরিবর্তে "একটি লিখতে class _Meta, তারপর লিখতে class Foo(models.Model)সঙ্গে Meta = _Meta";

class _Meta:
    ordering = ["horn_length"]
    verbose_name_plural = "oxen"

class Ox(models.Model):
    Meta = _Meta
    horn_length = models.IntegerField()
  • "নেস্টেড ক্লাস" পদ্ধতির সাথে কোডটি নেস্টেড বুলেট পয়েন্ট তালিকাটি পড়তে পারে তবে "রেফারেন্সড ইনার ক্লাস" পদ্ধতির সাহায্যে _Metaতার "শিশু আইটেম" (বৈশিষ্ট্যগুলি) দেখার সংজ্ঞাটি দেখতে ব্যাক আপ করতে হবে ।

  • যদি আপনার কোড নেস্টিংয়ের স্তর বৃদ্ধি পায় বা সারিগুলি অন্য কোনও কারণে দীর্ঘ হয় তবে "রেফারেন্সড ইনার ক্লাস" পদ্ধতিটি আরও পঠনযোগ্য হতে পারে।

* অবশ্যই স্বাদের বিষয়

৩.৩ কিছুটা ভিন্ন ত্রুটি বার্তা

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

innercls1.foo()
# AttributeError: type object 'Inner' has no attribute 'foo'

innercls2.foo()
# AttributeError: type object '_InnerClass' has no attribute 'foo'

এটি কারণ typeঅভ্যন্তরীণ ক্লাসগুলির এস

type(innercls1())
#mypackage.outer1.MyOuter1.Inner

type(innercls2())
#mypackage.outer2._InnerClass

0

আমি পাইথনের অভ্যন্তরীণ ক্লাসগুলি ইউনিটেটেস্ট ফাংশনগুলির মধ্যে ইচ্ছাকৃত বগি সাবক্লাসগুলি তৈরি করার জন্য ব্যবহার করেছি (অর্থাত্ অভ্যন্তরীণ def test_something():) যাতে 100% পরীক্ষার কভারেজের কাছাকাছি যেতে পারে (উদাহরণস্বরূপ কিছু পদ্ধতি ওভাররাইড করে খুব কমই ট্রিগারযুক্ত লগিং স্টেটমেন্টগুলি পরীক্ষা করা)।

পূর্ববর্তী ক্ষেত্রে এটি এডের উত্তরের সাথে মিলে যায় https://stackoverflow.com/a/722036/1101109

এই জাতীয় অভ্যন্তর শ্রেণিগুলির সুযোগের বাইরে চলে যাওয়া উচিত এবং একবার তাদের সমস্ত উল্লেখ মুছে ফেলা হলে আবর্জনা সংগ্রহের জন্য প্রস্তুত হওয়া উচিত । উদাহরণস্বরূপ, নিম্নলিখিত inner.pyফাইলটি নিন:

class A(object):
    pass

def scope():
    class Buggy(A):
        """Do tests or something"""
    assert isinstance(Buggy(), A)

আমি ওএসএক্স পাইথন ২.7..6 এর অধীনে নিম্নলিখিত কৌতূহলী ফলাফল পেয়েছি:

>>> from inner import A, scope
>>> A.__subclasses__()
[]
>>> scope()
>>> A.__subclasses__()
[<class 'inner.Buggy'>]
>>> del A, scope
>>> from inner import A
>>> A.__subclasses__()
[<class 'inner.Buggy'>]
>>> del A
>>> import gc
>>> gc.collect()
0
>>> gc.collect()  # Yes I needed to call the gc twice, seems reproducible
3
>>> from inner import A
>>> A.__subclasses__()
[]

ইঙ্গিত - যান এবং জ্যাঙ্গো মডেলগুলির সাথে এটি করার চেষ্টা করবেন না, যা আমার বগী ক্লাসে অন্যান্য (ক্যাশেড?) রেফারেন্স রাখবে বলে মনে হয়।

সুতরাং সাধারণভাবে, আমি এই ধরণের উদ্দেশ্যে অভ্যন্তরীণ ক্লাসগুলি ব্যবহার করার পরামর্শ দেব না যদি আপনি 100% পরীক্ষার কভারেজকে সত্যই মূল্য না দেন এবং অন্যান্য পদ্ধতি ব্যবহার করতে না পারেন। যদিও আমি মনে করি এটি সচেতন হতে খুব ভাল যে আপনি যদি __subclasses__()এটি ব্যবহার করেন তবে এটি কখনও কখনও অভ্যন্তরীণ শ্রেণীর দ্বারা দূষিত হতে পারে । যে কোনও উপায়ে যদি আপনি এটিকে অনুসরণ করে চলেছেন তবে আমার মনে হয় আমরা পাইথনের গভীর পর্যায়ে এই মুহুর্তে, ব্যক্তিগত ডানডোরস্কোর এবং সমস্ত কিছু।


4
এগুলি কি সাবক্লাস সম্পর্কে নয় এবং অভ্যন্তরীণ ক্লাসগুলি নয় ?? এ
ক্লাস

উপরের ক্যাসে বাগিটি এ থেকে উত্তরাধিকার সূত্রে আসে তাই সাবগ্লাস এটি দেখায়। এছাড়াও বিল্ট-ইন ফাংশন ইস্যুব্লক্লাস ()
ক্লাস

ধন্যবাদ ক্লেয়াস, আমি মনে করি এটি পরিষ্কার করে দেওয়া যেতে পারে যে আমি .__subclasses__()পাইথনের জিনিসপত্রের বাইরে না যাওয়ার সময় অভ্যন্তরীণ শ্রেণিগুলি কীভাবে আবর্জনা সংগ্রাহকের সাথে ইন্টারেক্ট করে understand এটি দৃশ্যত পোস্টটিতে আধিপত্য বিস্তার করে বলে মনে হচ্ছে সুতরাং প্রথম 1-3 অনুচ্ছেদগুলি আরও কিছুটা প্রসারণের যোগ্য।
pzrq
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.