# 类的组成成员分类 Python 类的组成成员可以分为三大类:字段(变量)、​​​方法(函数)和​​​​属性(特殊方法),它们的定义方式、作用域和调用规则各有不同。 ## 字段(变量) 字段分为​​实例变量​​和​​类变量​​,核心区别在于存储位置和作用对象: - 实例变量:每个对象独立拥有一份实例变量,修改不影响其他对象。 - 类变量:通过类名或实例均可访问,但通过实例修改会创建同名实例变量,覆盖类变量。 **示例:** ```python class Dog: species = "Canis lupus" # 类变量 def __init__(self, name): self.name = name # 实例变量 d = Dog("Buddy") print(d.name) d1 = Dog() print(Dog.species) d1.species = "Mutt" print(Dog.species) ``` ## 方法(函数) 方法分为实例方法​​、​​类方法​​和​静态方法​​,区别在于参数和调用方式: - 实例方法:第一个参数为 self,指向调用该方法的实例;必须通过对象调用,可访问实例变量和类变量。 - ​​类方法:使用 @classmethod 装饰器,参数为 cls(指向类本身);操作类变量或实现工厂模式(创建实例)。 - ​静态方法:使用 @staticmethod 装饰器,无默认参数,不依赖类或实例状态;执行与类相关的工具函数。 **示例:** ```python class Dog: species = "Canis lupus" # 类变量 def __init__(self, name, age=0): self.name = name # 实例变量 self.age = age def bark(self): print(f"{self.name} is barking!") @classmethod def create_from_string(cls, s): name, age = s.split(",") return cls(name, int(age)) # 创建实例时调用__init__方法 @classmethod def get_species(cls): return cls.species @staticmethod def describe(): return "Dogs are domesticated animals." d = Dog("Buddy", 11) d.bark() # Buddy is barking! d1 = Dog.create_from_string("Max,5") # 通过类方法创建实例 d2 = Dog("Bella", 3) # 通过类方法创建实例 print(d2.name) print(d1.age) print(Dog.get_species()) # 类方法调用 d3 = Dog("Charlie", 2) print(d3.get_species()) # 实例调用 print(Dog.describe()) # 静态方法调用 ``` ## 属性(Property) 属性是​​伪装成字段的方法​​,通过 @property 装饰器实现,用于封装逻辑。 ```python class BankAccount: def __init__(self, balance): self.__balance = balance @property def balance(self): return self.__balance @balance.setter def balance(self, value): if value >= 0: self.__balance = value @balance.deleter def balance(self): del self.__balance account = BankAccount(100) print(account.balance) # 调用getter方法 account.balance = 200 # 调用setter方法 del account.balance # 删除属性 print(account.balance) ``` ## 其他特殊成员 - 魔术方法:如 `__init__`(构造函数)、`__str__`(字符串表示)等,用于自定义类的行为。 - 私有成员:通过双下划线前缀(如 __variable)实现封装,仅在类内部访问。 **示例**: ```python class MyClass: def __init__(self, value): self.value = value # 公有属性 self.__value = value # 私有属性 def public_method(self): return f'这是类的公有方法, value: {self.value}' def __private_method(self): return f'这是类的私有方法, value: {self.__value}' def get_value(self): return self.__value # 通过公有方法访问私有属性 obj = MyClass(10) print(obj.value) # 访问公有属性 print(obj.public_method()) # 调用公有方法 print(obj.__value) # 访问公有属性 print(obj.__private_method()) # 调用私有方法 ``` # 案例 **需求** - 设计一个 `Game` 类 - 属性: - 定义一个类属性 `top_score` 记录游戏的历史最高分 - 定义一个实例属性 `player_name` 记录当前游戏的玩家姓名 - 方法: - 静态方法 `show_help` 显示游戏帮助信息 - 类方法 `show_top_score` 显示历史最高分 - 实例方法 `start_game` 开始当前玩家的游戏 - 主程序步骤 1. 查看帮助信息 2. 查看历史最高分 3. 创建游戏对象,开始游戏 ![img-方法综合案例](类的成员/方法综合案例.png) ```python class Game(object): # 游戏最高分,类属性 top_score = 0 @staticmethod def show_help(): print("帮助信息:让僵尸走进房间") @classmethod def show_top_score(cls): print("游戏最高分是 %d" % cls.top_score) def __init__(self, player_name): self.player_name = player_name def start_game(self): print("[%s] 开始游戏..." % self.player_name) # 使用类名.修改历史最高分 Game.top_score = 999 # 1. 查看游戏帮助 Game.show_help() # 2. 查看游戏最高分 Game.show_top_score() # 3. 创建游戏对象,开始游戏 game = Game("小明") game.start_game() # 4. 游戏结束,查看游戏最高分 Game.show_top_score() ``` # 总结 | 特性 | 普通方法 | 类方法 | 静态方法 | | :---------- | :------------------ | :---------------- | :-------------------- | | 定义方式 | 不需要装饰器 | `@classmethod` | `@staticmethod` | | 第一个参数 | `self` | `cls` | 无 | | 访问权限 | 访问实例属性和方法 | 访问类属性和方法 | 无法访问类和实例属性 | | 调用方式 | 通过实例调用 | 通过类或实例调用 | 通过类或实例调用 | | 适用场景 | 实例相关操作 | 与类相关的操作 | 与类无关的操作 | # isinstace 与 issubclass isinstance(a,b):判断a是否是b类(或者b类的派生类)实例化的对象 ```python class A: pass class B(A): pass obj = B() print(isinstance(obj,B)) print(isinstance(obj,A)) ``` issubclass(a,b): 判断a类是否是b类(或者b的派生类)的派生类 ```python class A: pass class B(A): pass class C(B): pass print(issubclass(B,A)) print(issubclass(C,A)) ``` 思考:那么 list str tuple dict等这些类与 Iterble类 的关系是什么? ```python from collections import Iterable print(isinstance([1,2,3], list)) # True print(isinstance([1,2,3], Iterable)) # True print(issubclass(list, Iterable)) # True # 由上面的例子可得,这些可迭代对象,list str tuple dict等 都是 Iterable 的子类。 ```