【问题标题】:Only pass an argument to a function if it takes that argument Python仅当函数接受该参数 Python 时才将参数传递给函数
【发布时间】:2020-06-09 13:27:45
【问题描述】:

我有一个像这样工作的“验证”方法:

def validate(self, allow_deferred_fields=False):
    """
    Validate the data in the group.
    Raises ValidationError if there is any incorrect data.
    """
    # Check custom validation of current group
    self.custom_validation()

custom_validation 方法会根据正在验证的组而有所不同。我的一个 custom_validation 定义我想像这样传递参数“allow_deferred_fields”:

def custom_validation(self, allow_deferred_fields=False):
    if allow_deferred_fields:
    .... some code

但其他 custom_validation 方法不采用此参数。如何将此参数传递给 validate 方法中的 custom_validation 调用,而不必将其作为参数添加到它可能调用的所有其他 custom_validation 方法?

【问题讨论】:

  • 对不起,我听不懂你想说什么,你能添加其他 custom_validator 的定义吗?你去过**kwargs, *args吗?你知道python中的方法重载吗?

标签: python parameter-passing


【解决方案1】:

这是一个设计问题。目前,validate 的“合同”的一部分是它将调用带有零参数的方法custom_validation。您需要更改 validate 以接受要传递的其他参数:

def validate(self, *args, **kwargs):
    self.custom_validation(*args, **kwargs)

或者您需要将标志“嵌入”到对象本身中,以便custom_validation 在调用时可以访问它。

def validate(self):
    self.custom_validation()

def custom_validation(self):
    if self.allow_deferred_fields:
        ...

...
obj.allow_deferred_fields = True
obj.validate()

不过,第二个选项有点小技巧。这并不比拥有一个custom_validation 检查的全局变量好多少。

第三个选项是强制所有自定义验证方法在validate调用时接受(可能是任意的)关键字参数,尽管它们可以随意忽略参数。

【讨论】:

    【解决方案2】:

    在这种情况下,很难检查函数是否接受参数(参见inspect.signature),但如果函数不支持参数,调用函数并捕获错误非常容易,前提是你知道该函数永远不会引发 TypeError

    这样做的好处是还可以使用基于 C 的函数。

    def validate(self, allow_deferred_fields=False):
        """
        Validate the data in the group.
        Raises ValidationError if there is any incorrect data.
        """
        # Check custom validation of current group
        try:
            self.custom_validation(allow_deferred_fields=True)
        except TypeError:
            self.custom_validation()
    

    如果你不能依赖永远不会抛出 TypeError 的函数,你可以尝试以下方法,但请记住,如果该函数是用 C 实现的,它将失败

    def validate(self, allow_deferred_fields=False):
        """
        Validate the data in the group.
        Raises ValidationError if there is any incorrect data.
        """
        # Check custom validation of current group
        if "allow_deferred_fields" in inspect.signature(self.custom_validation):
            self.custom_validation(allow_deferred_fields=True)
        else:
            self.custom_validation()
    

    【讨论】:

      猜你喜欢
      • 2021-04-13
      • 2015-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-27
      • 2013-06-23
      • 1970-01-01
      相关资源
      最近更新 更多