关于Python Self的权威指南

如果您很久以前开始进行Python编程,那么您会遇到“自我”一词。每当您使用Python进行面向对象的编程时,自我就会遇到您。您已经在方法定义和变量初始化中看到了。但是,在深入自我之前,让我们了解什么是类和实例变量以及什么是类和实例方法。

Python中的类变量

类变量是与该类的所有实例共享的变量的类型。这意味着,如果您要从实例访问类变量,则该值将相同。类变量是在类定义之后且在任何方法或函数之外定义的。

class MyClass:
    var_1 = "COVID_19"
    var_2 = 100
    var_3 = False

在此代码中,var_1,var_2和var_3是类变量。

Python中的实例变量

实例变量是所有实例都保留在其中的变量类型(即,特定对象拥有其实例变量)。因此实例变量的值因实例而异。

class MyClass:
    var_1 = "COVID_19"
    var_2 = 100
    var_3 = False


def __init__(self, param1, param2):
    self.instance_var1 = param1
    # instance_var1 is a instance variable
    
    self.instance_var2 = param2
    # instance_var2 is a instance variable

在此代码中,实例变量是instace_var1和instance_var2。

与类变量不同,实例变量应在方法内定义。

class MyClass:
    var_1 = "COVID_19"
    var_2 = 100
    var_3 = False

    def __init__(self, param1, param2, param3):
        self.instance_var1 = param1
        # instance_var1 is a instance variable

        self.instance_var2 = param2
        # instance_var2 is a instance variable

        self.instance_var3 = param3
        # instance_var3 is a instance variable


obj1 = MyClass('Disease', 150, True)
print('The class variable is: ', obj1.var_1)
print('The instance variable is: ', obj1.instance_var1)

obj2 = MyClass('Rasparatory', 200, False)
print('The class variable is: ', obj2.var_1)
print('The instance variable is: ', obj2.instance_var2)

在此示例中,我们定义了三个类变量和三个实例变量。

然后,我们创建了两个实例,分别称为obj1和obj2。

现在,如果使用obj1和obj2访问类变量,则值将相同。在我们的示例中,我们可以使用不同的实例访问var_1和var_2,并且值与您在输出中看到的相同。

但是当我们使用不同的实例访问实例变量时,值是不同的。这是因为在实例化时,我们是通过__init __()方法提供值的,因此实例之间的值是不同的。

Python中的类方法

类方法对于设置或获取类的详细信息(状态)很有用。类方法具有应作为第一个参数放置的特定参数。这是一个cls参数,代表类。

class MyClass:
    var_1 = "COVID_19"
    var_2 = 100
    var_3 = False

    @classmethod
    def class_method(cls):
        print("the class method was called")
        return 1


print(MyClass.class_method())
print(MyClass.var_1)
print(MyClass.var_2)
print(MyClass.var_3)

在此示例中,我们使用@classmethod装饰器定义了类方法。这里的类方法是class_method,它以cls作为参数。创建实例方法时,它与self相同。

因此,当我们定义类方法时,将cls作为第一个参数传递,而当我们定义实例方法时,则将self作为第一个参数传递。

然后,我们仅使用类而非对象访问了类方法。我们还使用class访问了class变量。因此,即使不实例化对象,我们也可以按以下方式访问类方法。

MyClass.class_method()

因此,这就是您可以在Python中定义和访问类方法的方式。

Python中的实例方法

好的,我们已经看到了实例变量,类变量和类方法。现在,我们将看到实例方法。

定义实例方法时,方法的第一个参数应始终为self。但是,您可以随心所欲地为它命名,而不必为自己命名,但是该参数表示的含义将始终相同。这是一个坚持自我的更好主意,因为这是全球惯例。

class MyClass:

    def add(self, a, b):
        return a + b


obj = MyClass()
print(obj.add(11, 21))

在此示例中,我们定义了一个名为add()的实例方法,它带有两个参数。

然后我们实例化了一个对象并调用了add()方法。

从上面的代码中您可以注意到,尽管在定义实例方法时,第一个参数是self。当我们调用该方法时,我们不会为自己传递任何东西作为参数。

Python中的自我是什么

self关键字用于表示给定类的实例(对象)。在上述情况下,obj对象具有其自己的a和b属性。如果没有自变量,则同一类不能包含有关该对象的信息。

但是,由于类是一个蓝图,因此self允许访问Python中每个对象的属性和方法。这使每个对象都有其属性和方法。这就是为什么甚至在创建这些对象之前,我们在定义类时就将这些对象引用为self的原因。

明确定义自己

即使我们知道self的用法,这似乎也很奇怪,特别是对于来自其他编程语言的程序员而言,每次定义实例方法时,self都会作为参数显式传递。

class MyClass:

    def __init__(self, a, b):
        self.a = a
        self.b = b

    def multi(self):
        return self.a * self.b


obj = MyClass(3, 7)
print('The multiplication of a and b is: ', obj.multi())

如果运行上面的代码,您将获得以下输出。

The multiplication of a and b is:  21

在上面的示例中,__init __()定义了三个参数,但我们仅传递了两个参数(3和7)。同样,multi()函数需要一个,但是在调用obj.multi()函数时传递了零个参数。为什么这不会给出错误?

引擎盖下会发生什么

当我们使用某些参数调用实例方法时,相关类函数会通过将方法的对象放在第一个参数之前来调用。因此,像obj.multi(args)之类的东西都会变成Class.multi(obj,args)。调用过程是自动的,而接收过程不是(它的显式)。

这是在类中函数的第一个参数必须是对象本身的主要原因。将此参数写为self纯粹是一种约定。它不是关键字,在Python中没有特殊含义。我们可以使用其他名称,但不建议使用。大多数人都不喜欢使用self以外的名称,这会降低代码的可读性。

到目前为止,您已经很清楚,对象(实例)本身是作为第一个参数自动传递的。进行静态方法时可以避免隐式行为。我们已经在本文前面看到了类方法。

显式自我并不是Python独有的。这个想法是从Modula-3借来的。

Python __init __()

在Python中,__init __()方法不是构造函数。由于创建对象时调用__init __(),许多坦诚的程序员对此感到困惑。

如果仔细检查,您会发现__init __()中的第一个参数是对象本身(对象已经存在)。函数__init __()在创建对象后直接调用,并用于对其进行初始化。从技术上讲,构造函数是一种使对象本身成为对象的方法。在Python中,此方法是__new __()。此方法的典型签名如下。

__new__(cls, *args, **kwargs)

调用__new __()方法时,类本身将作为第一个参数自动传递(cls)。

同样,就像自己一样,cls只是一个命名约定。此外,* args和** kwargs用于在Python函数调用期间获取任意数量的参数。
在实现__new __()时要记住一些有意义的事情:

  1. 总是在__init __()之前调用__new __()。
  2. 第一个参数是类本身,它是隐式传递的。
  3. 始终从__new __()返回有效对象。不是强制性的,但其主要用途是创建和返回对象。

请参阅以下代码。

class MyClass:

    def __new__(cls, *args, **kwargs):
        print("__NEW__")
        print(cls)
        print(args)
        print(kwargs)

        # create our object and return it
        obj = super().__new__(cls)
        return obj

    def __init__(self, a, b):
        self.a = a
        self.b = b

    def multi(self):
        return self.a * self.b


obj = MyClass(3, 7)
print('The multiplication of a and b is: ', obj.multi())

输出量

__NEW__

(3, 7)
{}
The multiplication of a and b is:  21

此示例说明__new __()在__init __()之前被调用。我们还可以看到__new __()中的参数cls是类本身(点)。

最后,通过在对象基类上调用__new __()方法来创建对象。

在Python中,对象是派生所有其他类的基类。在上面的代码中,我们使用super()完成了此操作。

结论

现在您了解了为什么应该始终将self用作Python中实例方法的第一个参数,以及当我们调用实例方法时幕后发生的事情。我们已经看到了类和实例变量,类和实例方法,自我,为什么我们使用自我,自我命名约定。

Python本身就是这样。

资讯来源:由0x资讯编译自APPDIVIDEND,版权归作者Krunal所有,未经许可,不得转载
你可能还喜欢