Can I overload the {} operators for creating dicti

2019-07-31 09:39发布

问题:

I am making a derived variant of the dict class such that a dictionary value can be accessed through attribute access syntax (so instead of doing dictionary['foo'] you could do dictionary.foo.) This is what I have so far:

class dict(dict): 
    __getattr__ = dict.__getitem__

However, this snippet of my code gives it problems:

eventD = {'rrule_end':None}
. . .
. . .
#(some time later)
print event.rrule_end

This is because the { } operators for dictionary creation have not been overloaded. Is it possible to make the dictName = { } syntax create an instance of my derived class instead of an ordinary dictionary?

回答1:

No. You cannot override dict literal syntax. (You also can't override list literal syntax, or string literal syntax, or number literal syntax, or any literal syntax.)

You have to create the instance of your class explicitly. Give your class a name like MyDict and then do

eventD = MyDict({'rrule_end':None})


回答2:

no, you can't overload that syntax, but their are alternative things you can do.

convert a normal dictionary into your dictionary

my_dict( {'foo':bar, 'foo2':bar2} )

make your function accept key-args

my_dict( foo='bar', foo2='bar2' )

make up your own syntax for this dictionary. this is abusing python's overloadable operators and is a little complex to do. its a chain reaction, starting with my_dict<'foo'. overload the operator so it outputs another my_dict object and repeat the process, each time keeping a record of each value until if finally reaches the end object. then it calculates and spits out you own object object.

my_dict<'foo'|bar,'foo2'|'bar2'>end

EDIT:

I'm not sure the reason you want to do this, but this could be an alternative answer to your problem. you may also want to have a look at the vars built in function. this lets you get a dictionary of every attribute an object has. if the object changes, the dictionary changes automatically.

class dict_obj(object):
    def __init__(self, obj):
        self.obj = obj
        self.dict = vars(obj)

    def __getattr__(self, value):
        return self.dict[value]
    __getitem__ = __getattr__

you can use it like this

>>> class test:
    def __init__(self):
        self.value = 5


>>> obj = dict_obj(test())
>>> obj.value
5
>>> obj['value']
5