使用self和类名调用方法有什么区别?

5
class A:

    def __init__(self, text):
        self.printStats()
        A.printStats(text)

    def printStats(self):
        print(self)

a = A("Hello")

这将打印:

<A object at 0x7f47e2f08ac8>
Hello

为什么这个 (A.printStats(text)) 可以执行?我理解正在发生的事情(self引用text),但我不明白为什么。

3
self.instance_method() 相当于 Class.instance_method(self)。如果你的方法实际上并没有使用实例状态(例如访问self的属性),那么你可以传入任何东西。 - jonrsharpe
1
你正在将 text(在示例中为“Hello”)作为 printStatsself 参数传递,这真的不是你应该做的。但这就是为什么你看到打印了“Hello”的原因。 - Tagc
1
感谢您提出了一个拼写和语法都很好的问题!您不知道有多少低质量的首帖存在... - noɥʇʎԀʎzɐɹƆ
3个回答

5
A.printStats(text)

不会使用A实例来调用printStats,它调用的是一个字符串 - 没有传递self

def printStats(self):
    # <--- here, "self" if the string "Hello", not an instance of A.
    print(self)

A.printStats(self) 相当于 self.printStats。同样地,如果你有一个函数 printStatsWithPrefix

class A:
    def printStatsWithPrefix(self, prefix):
        ...  # function body goes here

要做这个,你需要调用A.printStatsWithPrefix(self, prefix)


关于样式的注释:根据Python惯例(PEP 8),函数名应该使用_lowercase_with_underscores


谢谢您的解释。您所说的“用字符串调用它”是什么意思?编辑:没事,我明白了。 - d9h
@d9h “调用” 意味着使用给定的参数执行一个函数。你已经执行了这个函数,但是你没有使用 self 作为 A 类的实例,而是使用了一个字符串。 - noɥʇʎԀʎzɐɹƆ

1
你的代码在Python 2中会失败,因为通过类调用方法需要类的第一个参数实际上是该类的实例。
在Python 3中,实现不那么严格,因为只需要第一个参数实现与类的实例相关的所需接口;不会执行任何关于参数是否是实例的检查。由于你实际上没有通过self访问任何实例方法/变量,在printStats中这个方法可以工作,并且它只是打印传递的字符串'hello'

1
当你创建一个类的实例时:

a = A('some text')
self参数将永久绑定到a,这是类背后的魔法。如果您尝试a.printStats('something'),则会引发错误,因为self参数已被a占用。您可以使用a.printFunction.__func__恢复原始未绑定self的函数。尝试a.printFunction.__func__('this will be self argument')
然而,当您不创建实例时,没有任何东西可以绑定self,因此self仍然可供使用。在这种情况下,您可以将A视为包含函数的简单字典。
A = {'__init__': someInitFunction,
     'printStats': printStatsFunction}

您必须记住,名称self是任意的,您可以使用任何单词,甚至是not_self


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接