在 Python 类中,属性分为类属性、实例属性和方法属性(包括实例方法、类方法、静态方法)。以下是全面解析:
一、类属性 (Class Attribute)
-
定义位置:类内部,所有方法之外
-
存储位置:类自身(
__dict__
) -
特点:所有实例共享同一份数据
-
内存分配:仅在类定义时创建一次
-
访问方式:
类名.属性
或实例.属性
class Config: # 类属性 API_KEY = "A1B2C3" COUNT = 0 def __init__(self): Config.COUNT += 1 # 修改类属性 # 访问 print(Config.API_KEY) # A1B2C3 conf1 = Config() conf2 = Config() print(conf1.COUNT) # 2 (所有实例共享) print(conf2.COUNT) # 2
二、实例属性 (Instance Attribute)
-
定义位置:通常在
__init__
方法中 -
存储位置:实例自身(
__dict__
) -
特点:每个实例独立拥有自己的副本
-
内存分配:每次实例化时创建
class User: def __init__(self, name): # 实例属性 self.name = name self.id = id(self) # 每个实例唯一 alice = User("Alice") bob = User("Bob") print(alice.name) # Alice print(bob.name) # Bob (独立存储) print(alice.id == bob.id) # False
三、方法属性 (Method Types)
1. 实例方法 (Instance Method)
-
定义:第一个参数为
self
(指向实例) -
调用:必须通过实例调用
-
用途:操作实例属性
2. 类方法 (Class Method)
-
装饰器:
@classmethod
-
定义:第一个参数为
cls
(指向类) -
调用:可通过类或实例调用
-
用途:操作类属性或创建工厂方法
class Logger:
log_level = "INFO"
@classmethod
def set_level(cls, level):
cls.log_level = level # 修改类属性
@classmethod
def from_dict(cls, config):
# 工厂方法创建实例
return cls(config.get("level"))
# 通过类调用
Logger.set_level("DEBUG")
print(Logger.log_level) # DEBUG
# 通过实例调用
logger = Logger()
logger.set_level("WARNING")
3. 静态方法 (Static Method)
-
装饰器:
@staticmethod
-
定义:无
self
或cls
参数 -
调用:可通过类或实例调用
-
用途:工具函数(与类相关但无需访问属性)
class MathUtils: @staticmethod def add(a, b): return a + b @staticmethod def circle_area(radius): return 3.14 * radius ** 2 # 无需实例化 print(MathUtils.add(3, 5)) # 8 print(MathUtils.circle_area(2)) # 12.56 # 实例也可调用 calc = MathUtils() calc.add(10, 20) # 30
关键对比表
特性 类属性 实例属性 实例方法 类方法 静态方法 定义位置 类内部顶层 __init__
中类内部 类内部+装饰器 类内部+装饰器 访问权限 类/实例 仅实例 需实例 类/实例 类/实例 首参数 无 无 self
cls
无 修改影响范围 全局共享 仅当前实例 实例状态 类级别 无状态影响 内存占用 1份/类 1份/实例 1份/类 1份/类 1份/类 典型用途 全局配置 对象特征 对象行为 工厂方法 工具函数
特殊场景解析
1. 动态添加属性
class Dog: pass # 动态添加类属性 Dog.species = "Canine" # 动态添加实例属性 d = Dog() d.name = "Buddy" # 仅影响当前实例
2. 属性覆盖规则
class Test: value = "类属性" # 类属性 def __init__(self): self.value = "实例属性" # 同名实例属性 t = Test() print(t.value) # "实例属性"(实例优先) print(Test.value) # "类属性"
3. 方法绑定机制
class Demo: def method(self): pass d = Demo() print(d.method) # <bound method Demo.method of <__main__.Demo object>> print(Demo.method) # <function Demo.method at 0x...> (未绑定)
最佳实践建议
-
类属性:用于常量、计数器等全局数据
-
实例属性:存储对象状态(始终在
__init__
中初始化) -
实例方法:90% 场景下的默认选择
-
类方法:实现替代构造器(工厂模式)
-
静态方法:组织工具函数(避免污染全局命名空间)
-
避免陷阱:
-
不要用可变对象(如列表)作为类属性的默认值
-
修改类属性时使用
类名.属性
而非实例.属性
# 错误示范(类属性陷阱) class Team: members = [] # 所有实例共享同一列表! t1 = Team() t1.members.append("Alice") t2 = Team() print(t2.members) # ["Alice"] 😱 # 正确做法 class CorrectTeam: def __init__(self): self.members = [] # 每个实例独立列表
-