سؤال

في بايثون، هل هناك طريقة لإنشاء فئة يتم التعامل معها مثل القاموس ولكن تكون المفاتيح محددة مسبقًا عند إنشاء مثيل جديد؟

هل كانت مفيدة؟

المحلول

ويمكنك بسهولة تقديم كل ما بني في النوع. هذه هي الطريقة التي كنت تفعل ذلك مع ديكت:

>>> class MyClass(dict):
...     def __init__(self, *args, **kwargs):
...             self['mykey'] = 'myvalue'
...             self['mykey2'] = 'myvalue2'
...
>>> x = MyClass()
>>> x['mykey']
'myvalue'
>>> x
{'mykey2': 'myvalue2', 'mykey': 'myvalue'}

وأنا لم أتمكن من العثور على وثائق بيثون التي تتحدث عن هذا، ولكن شعبية جدا الكتاب الغوص في بايثون (ومتاح مجانا على الإنترنت) لديه بعض الأمثلة على القيام بذلك.

نصائح أخرى

هل يمكن أن يكون أيضا فئة فرعية ديكت تقييد مفاتيح لقائمة محددة مسبقا، عن طريق تجاوز __setitem__()

>>> class LimitedDict(dict):
    _keys = "a b c".split()
    def __init__(self, valtype=int):
        for key in LimitedDict._keys:
            self[key] = valtype()
    def __setitem__(self, key, val):
        if key not in LimitedDict._keys:
            raise KeyError
        dict.__setitem__(self, key, val)


>>> limited = LimitedDict()
>>> limited['a']
0
>>> limited['a'] = 3
>>> limited['a']
3
>>> limited['z'] = 0

Traceback (most recent call last):
  File "<pyshell#61>", line 1, in <module>
    limited['z'] = 0
  File "<pyshell#56>", line 8, in __setitem__
    raise KeyError
KeyError
>>> len(limited)
3

نعم، في بيثون dict هي فئة، حتى تتمكن فئة فرعية ما يلي:

    class SubDict(dict):
        def __init__(self):
            dict.__init__(self)
            self.update({
                'foo': 'bar',
                'baz': 'spam',})

وهنا يمكنك تجاوز الأسلوب __init__() ديكت في (الأسلوب الذي يسمى عند إنشاء مثيل من الفئة). داخل __init__ لك طريقة __init__() أولا supercalss المكالمة، وهي ممارسة شائعة عند whant للتوسع في وظائف الفئة الأساسية. ثم قمت بتحديث نسخة جديدة من SubDictionary مع البيانات الأولية.

    subDict = SubDict()
    print subDict    # prints {'foo': 'bar', 'baz': 'spam'}

وأنا لست متأكد من أن هذا هو ما كنت أبحث عنه، ولكن عندما قرأت رسالتك فكرت على الفور كنت تبحث لتوليد مفاتيح حيوي لحساب التدريبات.

وخلافا لبيرل، الذي سوف نفعل ذلك لك بشكل افتراضي،


grep{$_{$_}++} qw/ a a b c c c /;
print map{$_."\t".$_{$_}."\n"} sort {$_{$b}$_{$a}} keys %_;

c   3
a   2
b   1
سوف

وبيثون لا تعطيك هذه مجانا:


l = ["a","a","b","c","c","c"]
d = {}
for item in l:
    d[item] += 1

Traceback (most recent call last):
  File "./y.py", line 6, in 
    d[item] += 1
KeyError: 'a'

ولكن، سوف defaultdict القيام بذلك نيابة عنك،


from collections import defaultdict
from operator import itemgetter

l = ["a","a","b","c","c","c"]
d = defaultdict(int)
for item in l:
    d[item] += 1

dl = sorted(d.items(),key=itemgetter(1), reverse=True)
for item in dl:
    print item

('c', 3)
('a', 2)
('b', 1)

ما عليك سوى إنشاء فئة فرعية من الإملاء وإضافة المفاتيح في ملف فيه طريقة.

class MyClass(dict)

def __init__(self):
    """Creates a new dict with default values""""

    self['key1'] = 'value1'

تذكر أنه في لغة بايثون، أي فئة "تتصرف مثل الإملاء" عادة ما يتم التعامل معها كواحدة، لذلك لا داعي للقلق كثيرًا بشأن كونها فئة فرعية، يمكنك بدلاً من ذلك تنفيذ أساليب الإملاء، على الرغم من أن النهج أعلاه هو ربما أكثر فائدة لك :).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top