“распаковка” переданного словаря в пространство имен функции в Python?

используйте java.nio.channels. FileLock в сочетании с java.nio.channels. FileChannel

30
задан Andrew Wagner 13 December 2009 в 20:24
поделиться

5 ответов

Вы всегда можете передать словарь в качестве аргумента функции. Например,

dict = {'a':1, 'b':2}
def myFunc(a=0, b=0, c=0):
    print(a,b,c)
myFunc(**dict)
30
ответ дан 27 November 2019 в 23:37
поделиться

If you like d.variable syntax better than d['variable'], you can wrap the dictionary in an almost trivial "bunch" object such as this:

class Bunch:
    def __init__(self, **kw):
        self.__dict__.update(kw)

It doesn't exactly bring dictionary contents into the local namespace, but comes close if you use short names for the objects.

10
ответ дан 27 November 2019 в 23:37
поделиться

Это похоже на идею вашего декоратора, но имеет более общий характер, так как позволяет передавать произвольное количество диктов в foo , а декоратор делает не нужно ничего знать о ключах в dicts или порядке аргументов при вызове базовой функции foo .

#!/usr/bin/env python
d1 = {'x':1,'y':2}
d2 = {'a':3,'b':4}

def unpack_dicts(f):
    def f_new(*dicts):
        new_dict={}
        for d in dicts:
            new_dict.update(d)
        return f(**new_dict)
    return f_new

@unpack_dicts
def foo(x,y,a,b):
    print x,y,a,b

foo(d1,d2)
# 1 2 3 4
5
ответ дан 27 November 2019 в 23:37
поделиться

I do not think you can get any more convenience for dict unpacking in Python. So, here comes the obligatory "if that hurts, don't do that" answer.

Mapping item access IS more cumbersome than attribute access in Python, so maybe you should pass instances of user-defined classes instead of dicts.

2
ответ дан 27 November 2019 в 23:37
поделиться

I think the common wisdom is "don't use the inspect module in production code", and I mostly agree with that. As such, I think it is a bad idea to do the following in production code. But, if you're working on a python that supports frames (like CPython), this should work:

>>> def framelocals():
...    return inspect.currentframe(1).f_locals
... 
>>> def foo(ns):
...    framelocals().update(ns)
...    print locals()
... 
>>> foo({'bar': 17})
{'ns': {'bar': 17}, 'bar': 17}

It just grabs the actual dict out of the caller's frame, which when called inside a function body, should be the function's name space. I don't know if there is or isn't a situation when using CPython when locals() doesn't just do this anyway; the warning in the documentation might be to say "the effects of modifying the dict returned by locals() are python implementation dependent". Thus, while it works to modify that dict in CPython, it may not in another implementation.

UPDATE: This method doesn't actually work.

>>> def flup(ns):
...    framelocals().update(ns)
...    print locals()
...    print bar
... 
>>> flup({'bar': 17})
{'ns': {'bar': 17}, 'bar': 17}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in flup
NameError: global name 'bar' is not defined

As ddaa suggested, there's some deeper magic in the function compilation which makes note of the local variables. Thus you can update the dict, but you can't see the update with normal local namespace lookup.

2
ответ дан 27 November 2019 в 23:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: