python中类的常用知识
·
目录
1.基本结构与__init__
class Dog:
# 类属性(所有实例共享)
species = "Canis familiaris"
def __init__(self, name, age):
# 实例属性(每个实例独有)
self.name = name
self.age = age
def bark(self):
return f"{self.name} says woof!"
类属性 vs 实例属性——类属性被所有实例共享,实例属性各自独立。
2.继承与super()
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "..."
class Cat(Animal):
def __init__(self, name, color):
super().__init__(name) # 调用父类 __init__
self.color = color
def speak(self): # 重写父类方法
return f"{self.name} says meow"
super()使用的场景:
class Child(Parent):
def method(self):
super().method() # 扩展父类行为,而非完全覆盖
# 额外的子类逻辑...
3.@property装饰器
将方法伪装成属性,实现 getter/setter 的优雅写法:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self): # getter
return self._radius
@radius.setter
def radius(self, value): # setter
if value < 0:
raise ValueError("半径不能为负")
self._radius = value
@property
def area(self): # 只读计算属性
return 3.14159 * self._radius ** 2
# 使用
c = Circle(5)
print(c.area) # 78.53975 —— 像属性一样访问
c.radius = 10 # 触发 setter 校验
4.常用的魔法方法
__str__和__repr__
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self): # 给用户看的,print()调用
return f"Point({self.x}, {self.y})"
def __repr__(self): # 给开发者看的,调试用
return f"Point(x={self.x}, y={self.y})"
print(p) # Point(1, 2) ← 漂亮!好读!
__eq__、__lt__、__len__、__getitem__
这些魔术方法的作用是:让你自己的对象也能用 Python 的内置操作符和函数,比如:==、<、len()、[]等
class Book:
def __init__(self, title, pages):
self.title = title
self.pages = pages
self.content = ["第1页内容", "第2页内容", "第3页内容"]
def __eq__(self, other): # == 比较
return self.pages == other.pages
def __lt__(self, other): # < 比较(排序用)
return self.pages < other.pages
def __len__(self): # len() 调用
return self.pages
def __getitem__(self, index): # obj[index] 支持索引
return self.content[index]
b1 = Book("A", 100)
b2 = Book("B", 100)
print(b1 == b2) # True ← 因为页数都是 100
print(len(b1)) # 100 ← 你写 len(b),Python 自动调 b.__len__()
print(b[0]) # 第1页内容 ← 你写 b[0],Python 自动调 b.__getitem__(0)
print(b[1]) # 第2页内容
5.@classmethod与@staticmethod
class Date:
def __init__(self, year, month, day): # ① 实例方法:操作具体对象
self.year = year
self.month = month
self.day = day
@classmethod
def from_string(cls, date_str): # ② 类方法:用类来造对象(工厂)
year, month, day = date_str.split("-")
return cls(int(year), int(month), int(day))
@staticmethod
def is_valid_date(year, month, day): # ③ 静态方法:纯工具函数
return 1 <= month <= 12 and 1 <= day <= 31
# ① 普通创建
d1 = Date(2024, 1, 1)
# ② 类方法:换种方式创建(传字符串)
d2 = Date.from_string("2024-1-1")
# ③ 静态方法:只是个工具,不用创建对象就能调用
print(Date.is_valid_date(2024, 13, 1)) # False
6.__slots__节省内存
class Point:
__slots__ = ('x', 'y') # 禁止动态添加属性,省内存
def __init__(self, x, y):
self.x = x
self.y = y
在 Python 里,每个普通对象内部都藏着一个"小字典",叫__dict__,专门用来存它的属性。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
p = Point(1, 2)
print(p.__dict__) # 输出:{'x': 1, 'y': 2}
不加__slots__的代价:
1.费内存:字典为了"随时能加新东西",会预留很多空间。
2.可以随意乱加属性:
p = Point(1, 2)
p.z = 999 # 完全没报错!随便加了个 z
print(p.z) # 999
适用场景:创建大量实例时(百万级),显著减少内存占用。
7.私有属性
class BankAccount:
def __init__(self):
self._protected = 42 # 约定:内部使用,但可以访问
self.__private = 100 # 名称改写:变成 _BankAccount__private
#方法也一样
def __secret_method(self): # 同样被改写_BankAccount__secret_method
pass
#单下划线
acc = BankAccount()
print(acc._protected) # 42 ← 完全可以访问,Python 不拦你
acc._protected = 999 # 也能改,一样不拦
#双下划线
#
print(acc.__private) # ❌ 报错!AttributeError,找不到
print(acc._BankAccount__private) # ✅ 100 ← 用改写后的真名才能访问
class Father:
def __init__(self):
self.__money = 100 # 实际存成 _Father__money
class Son(Father):
def __init__(self):
super().__init__()
self.__money = 5 # 实际存成 _Son__money(名字不一样!)
Python 会偷偷帮你改名字(这就是图里说的"名称改写机制 / name mangling")。
你写的是__private,Python 在背后把它改成了:_BankAccount__private
规则就是:_类名__变量名
8.__call__让实例可调用
class Counter:
def __init__(self):
self.count = 0
def __call__(self):
self.count += 1
return self.count
c = Counter()
print(c()) # 1
print(c()) # 2
9.组合优于继承
"组合优于继承"的意思是:想给一个类加功能时,优先把那个功能做成独立的类,然后让它"拥有"一个(组合),而不是硬去"继承"一堆父类。 这样关系更清晰、更灵活、复用性更强,还能避开多继承的菱形混乱。
# ✅ 组合的正确写法
# 1. 把"飞行"这个功能独立成一个类
class Wings:
def fly(self):
print("拍打翅膀,飞起来了!")
# 2. 狗"拥有"翅膀(has-a),而不是"是"鸟(is-a)
class Dog:
def __init__(self):
self.wings = Wings() # 组合:狗有一对翅膀
def bark(self):
print("汪汪汪")
def fly(self):
self.wings.fly() # 飞的时候,交给翅膀去做
# 3. 猫也想飞?给它也装一对就行,复用超方便
class Cat:
def __init__(self):
self.wings = Wings()
def fly(self):
self.wings.fly()
d = Dog()
d.bark() # 汪汪汪
d.fly() # 拍打翅膀,飞起来了! ← 狗获得了飞行能力,但它依然是狗,不是鸟
c = Cat()
c.fly() # 拍打翅膀,飞起来了! ← 同一个 Wings 类,猫也能用
更多推荐
所有评论(0)