Python中的类和实例属性


在Python编程语言中,类和实例是面向对象编程中最关键的两个概念。类是模板,实例是根据类创建的独特对象。所有对象的程序相同,但数据可能不同。

在本教程中,我们将学习Python中的类,如何实例化它们,什么是属性,以及Python中类属性和实例属性的区别。让我们从定义开始:

什么是类?

在Python中,类提供了一种将数据和功能捆绑在一起的方法。创建新类会创建一种新类型的对象,允许创建该类型的新的实例。Python中的每个类实例都可以附加属性来维护其状态。类实例也可以具有方法(由其类定义)来修改其状态。

什么是实例?

对象或实例

Python是一种面向对象的编程语言,它强调对象,即它主要强调函数。在Python中,对象基本上是将数据变量和作用于该数据的方法封装到单个实体中。Python中几乎所有东西都是对象,都有其属性和方法。即使运行“x = 5”,实际上也是从'int'类创建了一个对象。

Python的类属性是在类中包含的属性/变量。也就是说,它的作用域在Python类中。

Python中的类属性只创建单个副本,此单个副本由该特定类中的所有函数和对象共享和使用。

语法

class ClassName:
   some_string = 'test'  # this is a class attribute

对于该类的所有实例,它都将相同。让我们从此类创建两个对象,并查看输出。

示例

o1 = ClassName() o2 = ClassName() print(ClassName.some_string) print(o1.some_string) print(o2.some_string)

输出

# test
# test
# test

正如观察到的那样,类属性在所有从中创建的对象之间是共享的。此外,类属性可以通过类名.属性名以及对象.属性名来访问。也可以使用类名.属性名 = '新值'来更改属性值。

Python的实例属性是局部属性/变量,其作用域在使用该属性的特定函数中。

每次创建对象时,实例属性都会创建自己的新副本。实现此行为最常用的函数是__init__()方法。

语法

class SomeClass:
    def __init__(self, attr1, attr2):
        self.attr1 = attr1
        self.attr2 = attr2

可以将任意数量的属性传递给构造函数。每个对象如何获得自己的属性可以通过“self”在创建时引用对象来理解,因此“self”永远无法直接从类中访问。

示例

obj1 = SomeClass('test', 10) obj2 = SomeClass('hello', 15) print(obj1.attr1, obj1.attr2) print(obj2.attr1, obj2.attr2)

输出

# test 10
# hello 15

在这里我们可以看到每个对象都有其自己的属性值,并且只有对象本身可以访问它们。

因此,更改一个对象的属性不会影响其他对象。

实例属性使用与类属性相同的点(.)表示法进行访问。可以使用对象名.属性名 = '新值'来更改或重新赋值它们。

更改类属性值

更改它们的方式可能与更改实例属性的方式相同,毕竟为什么不呢?一个字,继承

让我们来看一个示例,在这个示例中,我们定义一个函数,每次调用该函数时都会将类属性的值乘以5。

示例

class ClassA: some_string = 'test' # this is a class attribute class_val = 2 # this is also a class attribute def update(self): ClassA.class_val *= 5 o1 = ClassA() o2 = ClassA() o1.update() print(ClassA.class_val) o2.update() print(ClassA.class_val)

输出

# 10
# 50

现在让我们创建一个从该类继承的新类。

示例

class ClassB(ClassA): pass new_obj = ClassB() print(ClassA.class_val, ClassB.class_val) new_obj.update() print(ClassA.class_val, ClassB.class_val)

输出

# 50 50
# 250 250

为什么新类对象可以更改其父类的属性及其自身的属性?更重要的是,如何修复它?

我们编写的内容有两个主要问题:

  • ClassB定义中的“pass”关键字

  • 以下代码:

def update(self):
    ClassA.class_val *= 5

简单地放置“pass”意味着ClassB没有自己的属性,它只是指向其父类。其次,由于我们的尝试,我们对类名进行了硬编码。

此外,调用此函数需要先创建一个对象,因为它需要“self”引用。相反,我们可以使用所谓的“类方法”,它具有相同名称的装饰器。以下是它应该的样子:

@classmethod
    def update(cls):
        cls.class_val *= 5

它基本上表示我们只想更改从其调用的特定类的属性。让我们来看一个例子,使事情更清楚。

最后,我们的两个类应该如下所示:

示例

class OldClass: some_string = 'test' # this is a class attribute class_val = 2 # this is also a class attribute @classmethod def update(cls): cls.class_val *= 5 class NewClass(OldClass): class_val = 2 # this is different from the parent class

现在是时候分别从两个类调用更新函数了。

print("Initially:", OldClass.class_val, NewClass.class_val) OldClass.update() print("After calling update on old class once:", OldClass.class_val, NewClass.class_val) NewClass.update() NewClass.update() print("After calling update on new class twice:", OldClass.class_val, NewClass.class_val)

输出

# Initially: 2 2
# After calling update on old class once: 10 2
# After calling update on new class twice: 10 50

因此,现在我们可以更改Python中的类属性而无需创建对象,即使在从父类继承之后,类方法也会知道要更改哪个类的属性。

更新于:2022年10月13日

1000+ 次浏览

开启你的职业生涯

完成课程获得认证

开始学习
广告