从接受可选命名参数的函数返回数据,** kwargs

时间:2014-07-27 06:20:10

标签: python parameters parameter-passing optional-parameters kwargs

我只是在学习** kwargs而且我可能正在扭转它的实际用途,所以这里有......

我有1个主要脚本,3个函数和一个dict: script.py, 建立(), 计费() NEWCUST() data = {}

setup()将调用billing(),billing()将调用newCust(),newCust将返回一个将用作setup()的id。

每个函数都会接受可选的命名参数,** kwargs,这是dict,data = {}

我只是简单地将dict传递给函数,直到它击中newCust(),其中 我操纵数据并希望返回一些其他数据。但似乎newCust()在分配给变量时无法返回其数据。数据一直很顺利。

             def setup(**kwargs):
                id = billing(**kwargs)
                analytics(id)

             ......

             def newCust(**kwargs):
                   username = kwargs.get("ok",None)
                   id = callapi(username)
                   return id

             def billing(**kwargs):
                   id = newCust(**kwargs)
                   return id

            ......
             #calling the setup function which will begin passing the data along
             data = {'ok':1, 'okk':2, 'okkk':3}
             setup(**data)

1 个答案:

答案 0 :(得分:1)

函数有几种方法可以"返回"数据:

  • 使用return语句。如果您有多个值要返回,则用户元组(return (a, b, c))或dicts(return {'customer': c, 'customer_data': d, 'whatever': e}

  • (我不喜欢这个)通过利用可变对象传递给函数"通过引用"这一事实。这意味着如果函数接收到空字典并填充它,该函数的调用者将看到更改。一个重要的警告:如果您的函数创建了一个具有相同名称的新对象,则引用将被破坏。

说明我的第二点:考虑函数:

def f(**kwargs):
    if 'data' in kwargs:
        data = kwargs['data'] #reference to data outside the function
    else:
        data = dict() #new object
    data['zero'] = 0
    data['zero_1'] = 0
    data['zeven'] = 7
    print('data is %s' % repr(data))

以下是如何运作的:

In[14]: data = {'name': 'Bond'}

In [15]: f()
data is {'zero': 0, 'zeven': 7, 'zero_1': 0}

In [16]: data
Out[16]: {'name': 'Bond'}

In [17]: f(data=data)
data is {'zero': 0, 'zeven': 7, 'name': 'Bond', 'zero_1': 0}

In [18]: data
Out[18]: {'zero': 0, 'zeven': 7, 'name': 'Bond', 'zero_1': 0}

现在,当我们创建一个新对象时会发生什么?

def f(**kwargs):
    if 'data' in kwargs:
        data = dict(kwargs['data'])
        # A new object was created. This is a shallow copy
        # meaning that all its non-mutable objects are copied.
        # Mutable objects, on the other hand are still
        # referenced
        # See http://stackoverflow.com/q/17246693/17523 for
        # more details
    else:
        data = dict() #new object
        data['zero'] = [0, 0]
    data['zero'][0] = 'ZZEERROO'
    data['seven'] = 7
    data['last name'] = "Bond"
    print('data is %s' % repr(data))

正如您所看到的,这里f创建了一个新对象,它是现有对象的副本。不可变的值按原样复制,并且调用f对现有对象的值没有副作用。对应于键zero的值是一个列表(可变)。事实上,值是 reference to list,因此,当复制dict时,也会复制此引用。这就是为什么f仅对data的几个值产生副作用。