在(*args,**kwargs)python中,处理初始参数的简单方法是什么?

在(*args,**kwargs)python中,处理初始参数的简单方法是什么?,python,Python,基类如下所示(代码来自Django,但问题不是Django特有的): 派生类如下所示: class MyForm(forms.ModelForm): def __init__(self, data=None, files=None, *args, **kwargs): super(EdocForm, self).__init__(data, files, *args, **kwargs) self.Meta.model.get_others(data, f

基类如下所示(代码来自Django,但问题不是Django特有的):

派生类如下所示:

class MyForm(forms.ModelForm):
    def __init__(self, data=None, files=None, *args, **kwargs):
        super(EdocForm, self).__init__(data, files, *args, **kwargs)
        self.Meta.model.get_others(data, files, kwargs.get('instance', None))

如果编码器以kwargs的形式传递实例,这一切都很好,应该可以工作,但是如果他们不这样做,而是以args的形式传递呢?在处理*args和**kwargs时,提取实例的合理方法是什么?诚然,在这种情况下,实例位于args中的可能性很小,但如果它是第三个参数而不是第五个参数(不算self)。

在django中,如果实例未通过或未正确设置,则它将变为无,并且init将为您创建一个新实例 但这不是你的问题。 如果其他变量未正确设置,则可能会引发异常

如果你想检查用户是否正确使用了你的API,那就要看你了。在python中,这可能会让人望而生畏,而且检查实例类型也不是很像python,在web上有一个非常激烈的争论,关于拥有一种如此动态类型的语言是好是坏。一方面,在动态类型语言中,您可以非常高效;另一方面,您可能会遇到一些非常讨厌的bug,它们的解决方案并不那么明显,但这是我自己的经验

我相信一致性是一个系统可能拥有的最关键的东西之一,因此我倾向于总是使用关键字值,都设置为None,然后简单地执行断言以确保所需的不是None,您可以有一个只检查参数是否正确的函数。根据我自己的经验,关键字参数往往是最灵活的,因为你不需要跟踪顺序,你需要让被叫人记住它的名字


如果您真的需要“instance”,那么您可以使用isinstance在args和/或kwargs上迭代以获取实例变量,尽管正如我所说,这不是非常pythonic的….

在django中,如果实例未被传递或未正确设置,那么它将变为None,init将为您创建一个新实例 但这不是你的问题。 如果其他变量未正确设置,则可能会引发异常

如果你想检查用户是否正确使用了你的API,那就要看你了。在python中,这可能会让人望而生畏,而且检查实例类型也不是很像python,在web上有一个非常激烈的争论,关于拥有一种如此动态类型的语言是好是坏。一方面,在动态类型语言中,您可以非常高效;另一方面,您可能会遇到一些非常讨厌的bug,它们的解决方案并不那么明显,但这是我自己的经验

我相信一致性是一个系统可能拥有的最关键的东西之一,因此我倾向于总是使用关键字值,都设置为None,然后简单地执行断言以确保所需的不是None,您可以有一个只检查参数是否正确的函数。根据我自己的经验,关键字参数往往是最灵活的,因为你不需要跟踪顺序,你需要让被叫人记住它的名字


如果您确实需要“instance”,那么您可以使用isinstance在args和/或kwargs上迭代以获取实例变量,尽管正如我所说的,这不是很好的pythonic….

如果您坚持接受
*args
,如果获取
实例
MyForm
很重要,那么一种处理这种情况的方法就是,是将
instance
作为关键字参数显式包含到
MyForm
,将实例添加到kwargs,然后向上传递kwargs

class MyForm(forms.ModelForm):
    def __init__(self, data=None, files=None, instance=None, *args, **kwargs):
        kwargs['instance'] = instance
        super(EdocForm, self).__init__(data, files, *args, **kwargs)
请注意,如果有人将instance作为第三个位置参数,他们将犯一个非常明显的错误,因为instance是BaseModelForm的最后一个参数

但是,处理这种情况的更好方法是明确不允许额外的位置参数。例如:

class MyForm(forms.ModelForm):
    def __init__(self, data=None, files=None, **kwargs):
        super(EdocForm, self).__init__(data, files, *args, **kwargs)
        self.Meta.model.get_others(data, files, kwargs.get('instance', None))
这样,
MyForm
最多只能用2个位置参数调用。Python解释器将生成一个
TypeError:只接受2个参数(#给定)

如果需要使用
实例
参数,则应将其明确包含在
MyForm
的关键字参数中。否则,您至少应该在函数的文档字符串中记录它


如果您正在对BaseModelForm进行子类化,并且它有一个
self.instance
变量,那么您可以通过super直接访问它。例如,
self.instance=super(EdocForm,self).instance
。这样,您就可以让超类处理它需要对实例执行的任何操作,并为自己获取实例进行后期处理。(注意super的语法…您需要类和self)

如果您坚持接受
*args
,如果将
实例
事项添加到
MyForm
,处理这种情况的一种方法是显式地将
实例
作为
MyForm
的关键字参数,将实例添加到kwargs,然后递上夸尔格牌

class MyForm(forms.ModelForm):
    def __init__(self, data=None, files=None, instance=None, *args, **kwargs):
        kwargs['instance'] = instance
        super(EdocForm, self).__init__(data, files, *args, **kwargs)
请注意,如果有人将instance作为第三个位置参数,他们将犯一个非常明显的错误,因为instance是BaseModelForm的最后一个参数

但是,处理这种情况的更好方法是明确不允许额外的位置参数。例如:

class MyForm(forms.ModelForm):
    def __init__(self, data=None, files=None, **kwargs):
        super(EdocForm, self).__init__(data, files, *args, **kwargs)
        self.Meta.model.get_others(data, files, kwargs.get('instance', None))
这样,
MyForm
最多只能用2个位置参数调用。Python解释器将生成一个
TypeError:只接受2个参数(#给定)

如果需要使用
实例
参数,则应将其明确包含在
MyForm
的关键字参数中。否则,您至少应该在函数的文档字符串中记录它

如果您正在子类化BaseModelForm,并且它有一个
self.instance
变量,那么您可以直接访问它