【Python面向对象编程】第09篇 再谈类变量

本文深入探讨Python类属性的概念、用法和应用场景。类属性不同于实例属性,它们由类的所有实例共享,常用于存储常量、跨实例数据跟踪和设置默认值。示例中展示了如何定义和访问类属性,以及类属性在存储圆的π值、跟踪实例列表和设置产品默认折扣等场景中的应用。
摘要由CSDN通过智能技术生成

本篇我们继续学习 Python 类属性(变量)以及使用场景,类变量的基本概念可以参考第 3 篇

类属性简介

以下是一个简单的 Circle 类:

class Circle:
    def __init__(self, radius):
        self.pi = 3.14159
        self.radius = radius

    def area(self):
        return self.pi * self.radius**2

    def circumference(self):
        return 2*self.pi * self.radius

Circle 类拥有两个属性 pi 和 radius,以及两个计算圆的面积和周长的方法。

pi 和 radius 都是实例属性。也就是说,它们属于 Circle 类的具体实例。如果我们改变了某个实例的属性,不会影响其他实例。

除了实例属性之外,Python 还支持类属性。类属性不属于任何具体实例,它们由类的所有实例共享。

类属性和 Java 以及 C# 语言中的静态方法类似,但不完全相同。

类属性的定义位于 __init__() 方法之外。例如,以下示例定义了类属性 pi:

class Circle:
    pi = 3.14159

    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return self.pi * self.radius**2

    def circumference(self):
        return 2 * self.pi * self.radius

我们可以通过类的实例或者类名访问类属性:

object_name.class_attribute
class_name.class_attribute

area() 和 circumference() 方法通过 self 变量访问了类属性 pi。

在 Circle 类外部,我们可以通过类的实例或者直接通过类访问类属性 pi,例如:

c = Circle(10)
print(c.pi)
print(Circle.pi)

输出结果如下:

3.14159
3.14159

类属性的原理

当我们通过类的实例访问属性时,Python 首先会在实例的属性列表中查找属性,然后继续在类的属性列表中查找属性。一旦在实例的属性列表或者类的属性列表中找到了相应的属性,Python 会立即返回属性的值。

但是,如果我们直接通过类访问属性,Python 直接在类的属性列表中查找属性。以下示例定义了一个 Test 类,演示了 Python 如何处理实例属性和类属性:

class Test:
    x = 10

    def __init__(self):
        self.x = 20


test = Test()
print(test.x)  # 20
print(Test.x)  # 10

Test 类拥有两个同名的属性 x,其中一个是实例属性,另一个是类属性。当我们同实例访问属性 x 时,返回的是实例属性的值(20)。当我们通过 Test 类访问属性 x 时,返回的是类属性的值(10)。

类属性应用场景

类属性的实用场景包括存储类常量、跨实例的数据跟踪以及定义默认值。

存储类常量

常量不会随着实例的不同而改变,因此非常适合使用类属性存储。

例如, Circle 类拥有一个常量 pi,它的值对所有实例都相同。因此,我们可以将 pi 定义为一个类属性。

跨实例数据跟踪

以下示例为 Circle 类增加了一个类属性 circle_list。当我们创建一个新的 Circle 类实例时,构造函数会将该实例增加到列表中:

class Circle:
    circle_list = []
    pi = 3.14159

    def __init__(self, radius):
        self.radius = radius
        # add the instance to the circle list
        self.circle_list.append(self)

    def area(self):
        return self.pi * self.radius**2

    def circumference(self):
        return 2 * self.pi * self.radius


c1 = Circle(10)
c2 = Circle(20)

print(len(Circle.circle_list))  # 2

定义默认值

有时候我们想要为类的所有实例设置一个默认值,就可以利用类属性实现。

以下示例定义了一个 Product 类,它的所有实例都会拥有一个默认的折扣率 default_discount:

class Product:
    default_discount = 0

    def __init__(self, price):
        self.price = price
        self.discount = Product.default_discount

    def set_discount(self, discount):
        self.discount = discount

    def net_price(self):
        return self.price * (1 - self.discount)


p1 = Product(100)
print(p1.net_price())
100

p2 = Product(200)
p2.set_discount(0.05)
print(p2.net_price())
190

总结

  • 类属性由类的所有实例共享。类属性的定义位于 __init__() 方法之外。
  • 通过 class_name.class_attribute 或者 object_name.class_attribute 访问类属性 class_attribute 的值。
  • 类属性可以用于存储类常量、实现跨实例的数据跟踪以及定义默认值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不剪发的Tony老师

为 5 个 C 币而折腰。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值