Python面向对象编程第09篇 再谈类变量
Posted 不剪发的Tony老师
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python面向对象编程第09篇 再谈类变量相关的知识,希望对你有一定的参考价值。
本篇我们继续学习 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 的值。
- 类属性可以用于存储类常量、实现跨实例的数据跟踪以及定义默认值。
以上是关于Python面向对象编程第09篇 再谈类变量的主要内容,如果未能解决你的问题,请参考以下文章