Temporarily unpack dictionary

时光毁灭记忆、已成空白 提交于 2019-12-04 09:22:18

You can change your function to

def f(a,d,c,**args):
    if a == 1 and d == 7:
        print c

then it will work even if you have other items in the dict.

You can use operator.itemgetter to minimize multiple indexing :

>>> if operator.itemgetter('a','d')(my_dictionary)==(1,7):
...      print operator.itemgetter('c')(my_dictionary)

And you can use it in a function :

>>> def get_item(*args):
...   return operator.itemgetter(*args)(my_dictionary)
... 
>>> 
>>> if get_item('a','d')==(1,7):
...      print get_item('c')
... 
5
muddyfish

To answer

So is there any syntax which would allow me to do something like this:

within my_dictionary:
if a == 1 and d == 7:
    print c

You can subclass dict so that it has with magic methods. To do this, the class must have __enter__ and __exit__ methods. You could then export the keys to the local scope of the with statement and clean them up with the exit method.

Using this answer I was able to create a subclass that did so:

import inspect
import ctypes

locals_to_fast = ctypes.pythonapi.PyFrame_LocalsToFast
locals_to_fast.restype = None
locals_to_fast.argtypes = [ctypes.py_object, ctypes.c_int]

class WithDict(dict):
    def __enter__(self):
        frame = self.get_frame()
        for k,v in self.iteritems():
            frame.f_locals[str(k)] = v
            locals_to_fast(frame, 1)

    def __exit__(self, exc_type, exc_value, traceback):
        frame = self.get_frame()
        for k in self.keys():
            del frame.f_locals[str(k)]

    def get_frame(self):
        return inspect.getouterframes(inspect.currentframe())[2][0]

A test case using your original example

my_dictionary = WithDict({'a':1,'c':5,'b':20,'d':7})
with my_dictionary:
    if a == 1 and d == 7:
        print c

prints 5

The variables get deleted when the with statement completes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!