在同一个类的方法中使用类/静态方法作为默认参数值

2024-05-15 14:46:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我想这样做:

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)

有人能做到

^{pr2}$

还有一些神奇的机器学习;最后一点我并不特别感兴趣,这只是我第一次想到的事情,作为在函数上下文中和从调用方的角度演示静态方法的使用。在

无论如何,这不起作用,因为is_silly_enough实际上不是一个函数:它是一个对象,其__get__方法将返回原始的is_silly_enough函数。它的“正常”意味着只有当它作为一个被引用的对象时。有问题的对象是由staticmethod()函数创建的,该函数位于SillyWalkis_silly_enough属性和最初用该名称定义的函数之间。在

这意味着为了从中使用默认值appraisal_method或者其调用者,我们必须

  • 调用appraisal_method.__get__(instance, owner)(...),而不是仅仅调用appraisal_method(...)
  • 或者将其指定为某个对象的属性,然后将该对象属性引用为我们调用的方法appraisal_method。在

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

我不希望使用None,因为我想让None传达不应调用该特定函数的消息。我想我可以使用其他一些值,比如False或{},但这似乎是一个)骇人的b)不得不写额外的几行代码,以及其他多余的文档,因为它似乎可以很简洁地表示为默认参数。在

最好的办法是什么?在


Tags: 对象方法函数selfreturn属性isdef
3条回答

不确定我是否能得到你想要的,但是使用getattr会更干净吗?在

>>> class SillyWalk(object):
    @staticmethod
    def ise(walk):
        return (False, "boo")
    def walk(self, am="ise"):
        wge, r = getattr(self, am)(self)
        print wge, r


>>> sw = SillyWalk()
>>> sw.walk("ise")
False boo

也许你首先需要的只是使用函数(而不是方法)?在

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)

请注意,evaluation的默认函数现在将是一个函数而不是一个方法,即使ismully_ough在创建类之后(在代码末尾)将被绑定为类方法。在

这意味着

^{pr2}$

但是

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

您可以用walk参数调用is\u-sly-unough,或使用.is\u-sly-yu-enough()调用walk实例。在

如果你真的想成为一个静态的方法,你可以随时添加

    is_silly_enough = staticmethod(is_silly_enough)

在定义步行之后的任何地方。在

最后我编写了一个(un)包装器函数,用于函数定义头中,例如

def walk(self, appraisal_method=unstaticmethod(is_silly_enough)):

这似乎真的很管用,至少它能让我那些不经检验就失效的医生们通过了。在

这里是:

^{pr2}$

更新:

我为unstaticmethod函数本身编写了doctest;它们也通过了。我仍然不能完全确定这是一个真正明智的做法,但它似乎确实有效。在

相关问题 更多 >