首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >签名中的显式参数不起作用?非常奇怪

签名中的显式参数不起作用?非常奇怪
EN

Stack Overflow用户
提问于 2011-08-16 01:02:58
回答 3查看 435关注 0票数 1

我试图理解为什么显式指定签名参数不起作用,而只是盲目地执行*args,**kwargs有效!我真的看不出这两者有多大区别?

不起作用的例子:

代码语言:javascript
复制
from django.db.models import CharField as _CharField

class CharField(_CharField):
    def get_db_prep_value(self, value, connection, prepared=False):
        if self.blank == self.null == self.unique == True and value == '':
            value = None

        return super(CharField, self).get_db_prep_value(value, connection, prepared) # <--- this does not work!

我得到了以下错误:

代码语言:javascript
复制
  File "/home/googledroid/Workspace/eclipse/gameproject/virtualenv/lib/python2.6/site-packages/django/db/models/fields/__init__.py", line 276, in get_db_prep_save
    return self.get_db_prep_value(value, connection=connection, prepared=False)
  File "/home/googledroid/Workspace/eclipse/gameproject/virtualenv/lib/python2.6/site-packages/django/db/models/fields/subclassing.py", line 53, in inner
    return func(*args, **kwargs)
  File "/home/googledroid/Workspace/eclipse/gameproject/src/fields/__init__.py", line 13, in get_db_prep_value
    return super(CharField, self).get_db_prep_value(value, connection, prepared)
  File "/home/googledroid/Workspace/eclipse/gameproject/virtualenv/lib/python2.6/site-packages/django/db/models/fields/subclassing.py", line 53, in inner
    return func(*args, **kwargs)
  File "/home/googledroid/Workspace/eclipse/gameproject/virtualenv/lib/python2.6/site-packages/django/db/models/fields/subclassing.py", line 53, in inner
    return func(*args, **kwargs)
TypeError: get_db_prep_value() got multiple values for keyword argument 'connection'

虽然这个很好用:

代码语言:javascript
复制
from django.db.models import CharField as _CharField

class CharField(_CharField):
    def get_db_prep_value(self, value, *args, **kwargs):
        if self.blank == self.null == self.unique == True and value == '':
            value = None

        return super(CharField, self).get_db_prep_value(value, *args, **kwargs) 

在django source,django.db.models.subclassing.call_with_connection_and_prepared.inner()中,我看到有一些kwargs的删除,但不完全确定为什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-16 01:32:52

问题是,connection参数应该始终作为关键字参数传入。django.db.models.fields.subclassing中的代码只检查它是否存在于kwargs字典中,如果不存在,它将发出一个DeprecationWarning并将其添加到其中。位置参数不会被检查,所以最后发生的事情是,您传递的位置参数都会被转发,但函数包装器默认提供的关键字参数也会被传入。这就是冲突的原因。

要让你的代码正常工作,你需要做的就是:

代码语言:javascript
复制
        return super(CharField, self).get_db_prep_value(value, connection=connection, prepared=prepared)

仅供参考,在开发版本中,所有这些包装器都被删除了,这意味着您当前的代码可能会对主干起作用。但是,最好将参数保留在kwargs中。

票数 3
EN

Stack Overflow用户

发布于 2011-08-16 01:36:19

我没有可用的django源代码,所以这只是一个猜测:

请注意,根据BarBaz中的调用签名,传递给Foo的内容会有所不同

代码语言:javascript
复制
class Foo(object):
    def get_db_prep_value(self,*args,**kwargs):
        print(args,kwargs)

class Bar(Foo):
    def get_db_prep_value(self,value,connection,prepared=False):
        super(Bar,self).get_db_prep_value(value,connection,prepared)

class Baz(Foo):
    def get_db_prep_value(self,*args,**kwargs):        
        super(Baz,self).get_db_prep_value(*args,**kwargs)

bar=Bar()
bar.get_db_prep_value(1,2,prepared=True)
# ((1, 2, True), {})

baz=Baz()
baz.get_db_prep_value(1,2,prepared=True)
# ((1, 2), {'prepared': True})

当您使用

代码语言:javascript
复制
super(Bar,self).get_db_prep_value(value,connection,prepared)

prepared被传递到位置参数列表args中。

但是当你使用

代码语言:javascript
复制
super(Baz,self).get_db_prep_value(*args,**kwargs)

prepared被传递到关键字dict kwargs中。

票数 0
EN

Stack Overflow用户

发布于 2011-08-16 03:28:59

对于使用"double splat“语法定义的函数(我称之为”double splat“),调用者必须显式为每个关键字参数提供字典键。我敢打赌,get_db_prep_value的定义与下面的第一个函数类似。

代码语言:javascript
复制
def usessplat(**kwargs):
  print 'connection = ' + kwargs.get('connection', 'None')

def nosplat(connection=None)
  print 'connection = ' + str(connection)

usessplat('foo')  # raises TypeError
nosplat('foo')  # no exception
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7068057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档