在同一个类的方法中使用类/静态方法作为默认参数值 [英] Using class/static methods as default parameter values within methods of the same class

查看:101
本文介绍了在同一个类的方法中使用类/静态方法作为默认参数值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做这样的事情:

class SillyWalk(object):
    @staticmethod
    def is_silly_enough(walk):
        return (False, "It's never silly enough")
    def walk(self, appraisal_method=is_silly_enough):
        self.do_stuff()
        (was_good_enough, reason) = appraisal_method(self)
        if not was_good_enough:
            self.execute_self_modifying_code(reason)
        return appraisal_method
    def do_stuff(self):
        pass
    def execute_self_modifying_code(self, problem):
        from __future__ import deepjuju
        deepjuju.kiss_booboo_better(self, problem)

的想法是某人可以做

>>> silly_walk = SillyWalk()
>>> appraise = walk()
>>> is_good_walk = appraise(silly_walk)

,并且还可以进行一些神奇的机器学习;这最后一点对我来说并不特别有意义,这只是我想到的第一件事,它是在函数内上下文中以及从调用者的角度来举例说明使用静态方法的一种方式。

and also get some magical machine learning happening; this last bit is not of particular interest to me, it was just the first thing that occurred to me as a way to exemplify the use of the static method in both an in-function context and from the caller's perspective.

无论如何,这是行不通的,因为 is_silly_enough 实际上不是一个函数:它是一个对象,其 __get __ 方法将返回原始的 is_silly_enough 函数。这意味着,当它被引用为对象属性时,它只能以常规方式工作。有问题的对象是由装饰器放置在 SillyWalk 的<$ c之间的 staticmethod()函数创建的$ c> is_silly_enough 属性和最初使用该名称定义的函数。

Anyway, this doesn't work, because is_silly_enough is not actually a function: it is an object whose __get__ method will return the original is_silly_enough function. This means that it only works in the "normal" way when it's referenced as an object attribute. The object in question is created by the staticmethod() function that the decorator puts in between SillyWalk's is_silly_enough attribute and the function that's originally defined with that name.

这意味着要使用默认值<$从 SillyWalk.walk 的调用者中调用c $ c> appraisal_method

This means that in order to use the default value of appraisal_method from within either SillyWalk.walk or its caller, we have to either


  • 致电 appraisal_method .__ get __(instance,owner)(...)而不是仅调用 appraisal_method(...)

  • 或将其分配为某些对象的属性,然后引用该对象属性作为我们称为 appraisal_method 的方法。

  • call appraisal_method.__get__(instance, owner)(...) instead of just calling appraisal_method(...)
  • or assign it as the attribute of some object, then reference that object property as a method that we call as we would call appraisal_method.

给出这些解决方案似乎都不都是Pythonic™,我想知道是否有更好的方法来获得这种功能。我实质上是想要指定一种方法,默认情况下,该方法应使用在同一类范围内定义的特定类或静态方法来执行其日常例程的一部分。

Given that neither of these solutions seem particularly Pythonic™, I'm wondering if there is perhaps a better way to get this sort of functionality. I essentially want a way to specify that a method should, by default, use a particular class or static method defined within the scope of the same class to carry out some portion of its daily routine.

我不想使用,因为我想允许传达不应该调用该特定函数的消息。我想我可以使用其他一些值,例如 False NotImplemented ,但似乎a)顽强b)令人讨厌必须写一些额外的代码行,以及其他多余的文档,以使它看起来像是作为默认参数相当简洁地表达出来的。

I'd prefer not to use None, because I'd like to allow None to convey the message that that particular function should not be called. I guess I could use some other value, like False or NotImplemented, but it seems a) hackety b) annoying to have to write an extra couple of lines of code, as well as otherwise-redundant documentation, for something that seems like it could be expressed quite succinctly as a default parameter.

最好的方法是什么?

推荐答案

也许您所需要的只是在函数中使用函数(而不是方法)。

Maybe all you need is to use the function (and not the method) in the first place?

class SillyWalk(object):
    def is_silly_enough(walk):
        return (False, "It's never silly enough")

    def walk(self, appraisal_function=is_silly_enough):
        self.do_stuff()
        (was_good_enough, reason) = appraisal_function(self)
        if not was_good_enough:
            self.execute_self_modifying_code(reason)
        return appraisal_function
    def do_stuff(self):
        pass
    def execute_self_modifying_code(self, problem):
        deepjuju.kiss_booboo_better(self, problem)

现在,即使将is_silly_enough在类创建后(在代码末尾)绑定为类方法,appraisal_function的默认值仍将是函数而不是方法。

Note that the default for appraisal_function will now be a function and not a method, even though is_silly_enough will be bound as a class method once the class is created (at the end of the code).

这意味着

>>> SillyWalk.is_silly_enough
<unbound method SillyWalk.is_silly_enough>

但是

>>> SillyWalk.walk.im_func.func_defaults[0] # the default argument to .walk
<function is_silly_enough at 0x0000000002212048>

您可以使用walk参数调用is_silly_enough,或使用.is_silly_enough()调用walk实例。

And you can call is_silly_enough with a walk argument, or call a walk instance with .is_silly_enough().

如果您确实希望is_silly_enough是静态方法,则可以随时添加

If you really wanted is_silly_enough to be a static method, you could always add

    is_silly_enough = staticmethod(is_silly_enough)

步行定义后的任何地方。

anywhere after the definition of walk.

这篇关于在同一个类的方法中使用类/静态方法作为默认参数值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆