为什么我们更喜欢使用self.method()而不是Class.method(self)

Phi*_*lly 2 python oop inheritance

例如,对于某些类:

class Class(object):
    def __init__(self):
        pass

    def something(self):    # yes I know this could be static
        print("something")
Run Code Online (Sandbox Code Playgroud)

和实例

instance = Class()
Run Code Online (Sandbox Code Playgroud)

以下都是技术上有效的:

instance.something()       # normal
Class.something(instance)  # but also technically valid
Run Code Online (Sandbox Code Playgroud)

是否有一些明确的推理为什么第一个用例是首选?我可以想到迭代实例和调用方法等示例,但我也可以想到一些情况,当我明确引用我正在使用的类时,可能更容易解释我的代码.

如果之前已经回答过,请道歉.我找不到它,这可能是由于我在措辞问题上的困难.

Mar*_*ers 7

Class.something(instance)特定类中获取方法.self.something()使用该实例的类,并且不一定是同一个类.

如果你必须继续使用类名,你也会重复很多.

您的标题使用self,表示方法内的代码.比较以下示例的输出:

class Animal:
    def make_sound(self):
        print('General nature sounds')

    def startle(self):
        self.make_sound()

    def pet(self):
        Animal.make_sound(self)

class Dog(Animal):
    def make_sound(self):
        # overrides Animal.make_sound()
        print('Bark!')

dog = Dog()
dog.startle()  # prints "Bark!"
dog.pet()      # prints "General nature sounds"
Run Code Online (Sandbox Code Playgroud)

Animal.make_sound(self)工作,但将使用原始方法,忽略新的实现Dog.make_sound().

对于您在其他地方引用实例的情况,请考虑接受类或子类的情况:

class Cat(Animal):
    def make_sound(self):
        print('Meouw!')

def groom_pet(pet):
    pet.startle()
    Animal.make_sound(pet)

groom_pet(Cat())  # prints "Meouw", then "General nature sounds"
Run Code Online (Sandbox Code Playgroud)

所以我们有一个新的子类Animal,并且groom_pet()可以接受任何Animal实例,因为子类也将具有相同的方法.但pet.startle()最终将调用正确的make_sound()实现,同时Animal.make_sound()将再次绕过正确的实现.

很少应该在实例上使用绑定方法的未绑定类方法.有时候有理由使用它; 特别是如果你想绕过父类方法(所以不使用super().method()),或者你想提高性能并避免查找属性并在紧密循环中绑定方法.

因为这种情况很少而且很特殊,所以你想要坚持正常的习惯用法,因为这有助于你自己和其他读者理解你的代码.不要让那些读者感到惊讶.