是否有任何理由给自己一个默认值?

时间:2016-09-02 21:27:12

标签: python class python-3.x

我正在浏览一些代码,我注意到一条引起我注意的行。代码类似于下面的示例

class MyClass:
    def __init__(self):
        pass

    def call_me(self=''):
        print(self)

这看起来像我见过的任何其他类,但str作为self的默认值传入。

如果我打印出self,则表现正常

>>> MyClass().call_me()
<__main__.MyClass object at 0x000002A12E7CA908>

这一直困扰着我,我无法弄清楚为什么要使用它。是否有任何理由将str实例作为self?

的默认值传入

2 个答案:

答案 0 :(得分:28)

不是,它只是一种奇怪的方式,在通过类调用时不会引发错误:

MyClass.call_me()

工作正常,因为即使没有像实例一样隐式传递,也提供了该参数的默认值。如果没有提供默认值,那么在调用时,这当然会为我们都喜欢的args提升TypeError。至于为什么他选择一个空字符串作为值,只有他知道

最重要的是,这比实际情况更令人困惑。如果你需要做类似的事情我会建议一个带有默认参数的简单staticmethod来实现类似的效果。

那样你不会把任何人读取你的代码(就像写这篇文章的开发人员一样; - ):

@staticmethod
def call_me(a=''):
    print(a)

如果您需要访问类属性,则可以随时选择classmethod装饰器。这两个(classstatic装饰器)也有一个次要目的,即让您的意图在阅读代码时清晰明了。

答案 1 :(得分:13)

简短的回答是肯定的。这样,您可以将函数调用为:

MyClass.call_me()

没有实例化MyClass,会打印一个空字符串。

为了给出更长的答案,我们需要了解幕后发生的事情。

创建类的实例时,会调用__new____init__来创建它,即:

a = MyClass()

大致相当于:

a = MyClass.__new__(MyClass)
MyClass.__init__(a)

每当您在创建的实例a上使用某种方法时:

a.call_me()

它被MyClass.call_me(a)“替换”。

因此,拥有call_me的默认参数允许您将此函数调用为一个实例的方法,在这种情况下self本身就是一个实例,但也作为一个静态类方法

这样,只需调用MyClass.call_me(a)而不是MyClass.call_me()。由于参数列表为空,因此默认参数将分配给self,并打印所需的结果(空字符串)。