说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
在 Python 中,类属性和实例属性是两个不同的概念。理解这两个属性的区别和用途对于编写清晰、高效的代码非常重要。类属性通常用于定义所有实例共享的数据。例如,动物种类、常量值、静态配置信息等。
类属性是直接在类体中定义的属性,不属于任何一个实例,而是属于类本身。所有的实例共享同一个类属性。当你修改类属性时,所有实例都能看到变化。实例属性是在类的每一个实例中独立存在的属性。它们通常在 __init__
方法中定义。每个实例都有自己的实例属性,互不影响。
在 Python 中,属性可以分为实例属性和类属性:
__init__
方法中定义的,属于特定实例,每个实例都有自己的独立属性。假设我们要创建一个计数器类,每创建一个新的计数器实例,总的计数器数目就会增加,这样我们可以跟踪一共创建了多少个计数器实例。
class Counter:
# 类属性,用于跟踪创建的实例数
count = 0
def __init__(self, name):
# 实例属性
self.name = name
# 每创建一个新实例,类属性 count 增加
Counter.count += 1
def __del__(self):
# 实例被销毁时,类属性 count 减少
Counter.count -= 1
# 创建三个 Counter 实例
c1 = Counter("Counter 1")
c2 = Counter("Counter 2")
c3 = Counter("Counter 3")
# 输出类属性 count
print(Counter.count) # 输出: 3
# 销毁一个实例
del c1
# 输出类属性 count
print(Counter.count) # 输出: 2
解释:
运行流程:
这个例子展示了类属性如何在所有实例之间共享并用于跟踪全局状态,而实例属性则用于存储每个实例独有的数据。
在 Python 中,类属性的增加、修改和删除可以通过类本身或者类的实例来操作。可以直接在类体中定义类属性,或者在类外部动态添加类属性。类属性可以通过类本身或者任何一个实例来修改。然而,最好通过类本身来修改类属性以避免混淆。可以使用 del 语句删除类属性。
下面是一个更完整的示例,展示如何增加、修改和删除类属性。
class Example:
class_attr = 10
# 创建实例
e1 = Example()
e2 = Example()
# 访问类属性
print(Example.class_attr) # 输出: 10
print(e1.class_attr) # 输出: 10
print(e2.class_attr) # 输出: 10
# 修改类属性
Example.class_attr = 20
print(Example.class_attr) # 输出: 20
print(e1.class_attr) # 输出: 20
print(e2.class_attr) # 输出: 20
# 动态增加类属性
Example.new_class_attr = 30
print(Example.new_class_attr) # 输出: 30
print(e1.new_class_attr) # 输出: 30
print(e2.new_class_attr) # 输出: 30
# 删除类属性
del Example.class_attr
# 尝试访问已删除的类属性
try:
print(Example.class_attr)
except AttributeError as e:
print(e) # 输出: type object 'Example' has no attribute 'class_attr'
# 检查实例是否还能访问已删除的类属性
try:
print(e1.class_attr)
except AttributeError as e:
print(e) # 输出: type object 'Example' has no attribute 'class_attr'
以下是一个关于商品打折的应用,通过类属性可以设置统一的折扣:
class Product:
discount = 0.5 # 类属性,所有实例共享
def __init__(self, name, price):
self.name = name # 实例属性
self.price = price # 实例属性
def get_price_after_discount(self):
return self.price * (1 - Product.discount)
# 创建实例
p1 = Product('Laptop', 1000)
p2 = Product('Phone', 500)
# 输出打折后的价格
print(p1.get_price_after_discount()) # 输出: 500.0
print(p2.get_price_after_discount()) # 输出: 250.0
类属性在很多场景中都非常有用,尤其是当你需要在类的所有实例之间共享数据时。以下是几个常见的类属性用途和场景:
跟踪类的实例数目。通过类属性可以方便地记录和访问某个类已经创建的实例数量。
class Counter:
instance_count = 0
def __init__(self):
Counter.instance_count += 1
@classmethod
def get_instance_count(cls):
return cls.instance_count
c1 = Counter()
c2 = Counter()
print(Counter.get_instance_count()) # 输出: 2
类属性可以用于存储与类相关的常量或配置信息,例如数据库连接信息、默认配置参数等。
class Config:
DATABASE_URI = "sqlite:///:memory:"
DEBUG = True
print(Config.DATABASE_URI) # 输出: sqlite:///:memory:
print(Config.DEBUG) # 输出: True
当多个实例需要共享状态或数据时,类属性非常有用。例如,跟踪一个游戏中所有玩家的总得分。
class Player:
total_score = 0
def __init__(self, score):
self.score = score
Player.total_score += score
@classmethod
def get_total_score(cls):
return cls.total_score
p1 = Player(10)
p2 = Player(20)
print(Player.get_total_score()) # 输出: 30
类属性可以用来缓存计算结果或共享资源,以便所有实例都能访问,而无需每次都重新计算或创建。
class MathOperations:
_factorial_cache = {}
@classmethod
def factorial(cls, n):
if n in cls._factorial_cache:
return cls._factorial_cache[n]
if n == 0:
result = 1
else:
result = n * cls.factorial(n-1)
cls._factorial_cache[n] = result
return result
print(MathOperations.factorial(5)) # 输出: 120
print(MathOperations._factorial_cache)
# 输出: {5: 120, 4: 24, 3: 6, 2: 2, 1: 1, 0: 1}
类属性可以与类方法(使用 @classmethod
装饰器)或静态方法(使用 @staticmethod
装饰器)结合使用,以实现一些与类相关的操作或逻辑。
class MyClass:
class_attribute = 0
@classmethod
def increment_class_attribute(cls):
cls.class_attribute += 1
@staticmethod
def static_method_example():
return "This is a static method."
MyClass.increment_class_attribute()
print(MyClass.class_attribute) # 输出: 1
print(MyClass.static_method_example())
# 输出: This is a static method.
类属性在需要共享数据、配置常量、缓存结果以及跟踪状态时非常有用。它们提供了一种方便的方式来在类的所有实例之间共享信息,同时保持代码的简洁和高效。
更新时间:2024-06-16 16:38:36 标签:python 类 类属性 属性