ডিক এবং সংগ্রহগুলি থেকে উপক্লাসিংয়ের কোনও উপায় আছে?


26

আসুন উদাহরণস্বরূপ ধরে নেওয়া যাক আমি সাবক্লাস করতে চাই dictএবং সমস্ত কীগুলি মূলধনযুক্ত করতে চাই:

class capdict(dict):
    def __init__(self,*args,**kwds):
        super().__init__(*args,**kwds)
        mod = [(k.capitalize(),v) for k,v in super().items()]
        super().clear()
        super().update(mod)
    def __getitem__(self,key):
        return super().__getitem__(key.capitalize())
    def __setitem__(self,key,value):
        super().__setitem__(key.capitalize(),value)
    def __delitem__(self,key):
        super().__detitem__(key.capitalize())

এটি একটি পরিমাণে কাজ করে,

>>> ex = capdict(map(reversed,enumerate("abc")))
>>> ex
{'A': 0, 'B': 1, 'C': 2}
>>> ex['a']
0

তবে, অবশ্যই, প্রয়োগের জন্য কেবল মনে আছে সেই পদ্ধতিগুলির জন্য

>>> 'a' in ex
False

পছন্দসই আচরণ নয়।

এখন, "মূল "গুলি থেকে প্রাপ্ত সমস্ত পদ্ধতিতে পূরণ করার অলস উপায়টি মেশানো হবে collections.abc.MutableMapping। কেবল এটি এখানে কাজ করে না। আমি অনুমান করি কারণ প্রশ্নে পদ্ধতিগুলি ( __contains__উদাহরণস্বরূপ) ইতিমধ্যে সরবরাহ করা হয়েছে dict

আমার কেক খাওয়ার এবং এটি খাওয়ার কোনও উপায় আছে? কিছু জাদু MutableMappingকেবলমাত্র আমি যে পদ্ধতিগুলিকে ওভাররাইড করেছি তা কেবল দেখতে দিন যাতে এটি অন্যদের উপর ভিত্তি করে প্রতিস্থাপন করে?


আপনার ব্যবহারের প্রয়োজন হতে পারে না MutableMapping। দেখুন কেস অবশ অভিধান
মার্টিনিউ

@ মার্টিনাউ ধন্যবাদ, যেমন আমি বলেছি এটি একটি উদাহরণ মাত্র।
পল পান্জার

আপনি ব্যবহার করতে পারে os._Environ
পিটার উড

উত্তর:


26

আপনি কি করতে পারেন:

এটি সম্ভবত কার্যকরভাবে কাজ করবে না (অর্থাত্ সবচেয়ে পরিষ্কার নকশা নয়) তবে আপনি প্রথমে মিউটেবলম্যাপিং এবং তারপরে ডিক দ্বিতীয় হতে পারেন।

তারপরে মিউটেবলম্যাপিং আপনি যে কোনও পদ্ধতি প্রয়োগ করেছেন তা ব্যবহার করবে (কারণ তারা অনুসন্ধানের চেইনে প্রথম):

>>> class D(MutableMapping, dict):
        def __getitem__(self, key):
            print(f'Intercepted a lookup for {key!r}')
            return dict.__getitem__(self, key)


>>> d = D(x=10, y=20)
>>> d.get('x', 0)
Intercepted a lookup for 'x'
10
>>> d.get('z', 0)
Intercepted a lookup for 'z'
0

উত্তম উপায়:

সবচেয়ে পরিষ্কার পদ্ধতির (বোঝা ও পরীক্ষা করা সহজ) হ'ল কেবল মিউটেবলম্যাপিং থেকে উত্তরাধিকারী হওয়া এবং তারপরে নিয়মিত ডিক ব্যবহার করে বেস ডেটা স্টোর (উত্তরাধিকারের পরিবর্তে রচনা সহ) ব্যবহার করে প্রয়োজনীয় পদ্ধতিগুলি প্রয়োগ করা:

>>> class CapitalizingDict(MutableMapping):
        def __init__(self, *args, **kwds):
            self.store = {}
            self.update(*args, **kwds)
        def __getitem__(self, key):
            key = key.capitalize()
            return self.store[key]
        def __setitem__(self, key, value):
            key = key.capitalize()
            self.store[key] = value
        def __delitem__(self, key):
            del self.store[key]
        def __len__(self):
            return len(self.store)
        def __iter__(self):
            return iter(self.store)
        def __repr__(self):
            return repr(self.store)


>>> d = CapitalizingDict(x=10, y=20)
>>> d
{'X': 10, 'Y': 20}
>>> d['x']
10
>>> d.get('x', 0)
10
>>> d.get('z', 0)
0
>>> d['w'] = 30
>>> d['W']
30

ধন্যবাদ! আমি শপথ করতে পারি আমি উভয় আদেশই চেষ্টা করেছিলাম ... আগ্রহের বাইরে, যখন আমি superস্পষ্টভাবে dictএসগুলির জন্য সমস্তগুলি অদলবদল করতে "" করতে পারি "পদ্ধতিটি ব্যবহার করি তখন এটি lenরিটার্ন ব্যতীত কাজ করে বলে মনে হয় 0। কোথা থেকে আসছে?
পল

2
থেকে সুপার () কলের __len: _ () __ ম্রো পরবর্তী যায়: (D, MutableMapping, dict)। এটি হ'ল মিউটেবলম্যাপিং । এজন্য আপনাকে dict.__len__(self)সরাসরি কল করতে হবে । এবং এটি যে কারণগুলির মধ্যে একটি বলেছিলাম যে "এটি সম্ভবত ভাল কার্যকর হবে না" ;-)
রেমন্ড হেটিংগার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.