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

Won*_*ket 31 python class python-3.x

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

class MyClass:
    def __init__(self):
        pass

    def call_me(self=''):
        print(self)
Run Code Online (Sandbox Code Playgroud)

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

如果我打印出来self,它就像正常一样

>>> MyClass().call_me()
<__main__.MyClass object at 0x000002A12E7CA908>
Run Code Online (Sandbox Code Playgroud)

这一直困扰着我,我无法弄清楚为什么会这样.是否有任何理由将str实例作为默认值传入self?

Jim*_*ard 28

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

MyClass.call_me()
Run Code Online (Sandbox Code Playgroud)

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

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

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

@staticmethod
def call_me(a=''):
    print(a)
Run Code Online (Sandbox Code Playgroud)

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


Dmi*_*rba 13

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

MyClass.call_me()
Run Code Online (Sandbox Code Playgroud)

没有实例化MyClass,将打印一个空字符串.

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

当您创建该类的实例__new__并被__init__调用以创建它时,即:

a = MyClass()
Run Code Online (Sandbox Code Playgroud)

大致相当于:

a = MyClass.__new__(MyClass)
MyClass.__init__(a)
Run Code Online (Sandbox Code Playgroud)

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

a.call_me()
Run Code Online (Sandbox Code Playgroud)

它被"替换"了MyClass.call_me(a).

因此,有一个默认参数call_me允许您不仅将此函数作为实例的方法调用,在这种情况下self,实例本身,还可以作为静态类方法.

这样,而不是MyClass.call_me(a),只是MyClass.call_me()被称为.因为参数列表为空,所以分配了默认参数,self并打印了所需的结果(空字符串).