and, or, invert
classmethod
解锁 Python 类方法的精髓:classmethod 的应用技巧!
在 Python 中,类方法(class method)是一种特殊的方法,在不创建类的实例的情况下,可以调用。
类方法的第一个参数是类本身,通常命名为 cls。
类方法既可以通过类直接调用,也可以通过类的实例调用。
可以通过 cls 参数访问类的属性和方法,也可以通过 cls 参数调用其他类方法。
- 替代构造函数,类方法常用于创建替代的构造函数,提供不同的对象创建方式。
- 访问和修改类状态,类方法可以访问和修改类级别的属性。
class MyClass:
@classmethod
def my_class_method(cls, arg1, arg2):
# 类方法的实现
pass
my_class_method 就是一个类方法,可以通过 MyClass.my_class_method()直接调用。
组成
# Python 面向对象编程完整示例,下面是一个包含 Python 面向对象编程主要概念的完整示例:
from abc import ABC, abstractmethod
from typing import List, Optional
import json
# 1. 抽象基类 (抽象类)
class Animal(ABC):
"""动物抽象基类"""
# 类属性
kingdom = "Animalia"
def init(self, name: str, age: int):
# 实例属性
self._name = name # 受保护的属性
self.__age = age # 私有属性
self._species = "Unknown"
# 抽象方法
@abstractmethod
def make_sound(self) -> str:
pass
# 实例方法
def get_info(self) -> str:
return f"{self._name} is {self.__age} years old"
# 类方法
@classmethod
def get_kingdom(cls) -> str:
return cls.kingdom
# 静态方法
@staticmethod
def is_animal(obj) -> bool:
return isinstance(obj, Animal)
# 属性装饰器 (getter)
@property
def name(self) -> str:
return self._name
# 属性装饰器 (setter)
@name.setter
def name(self, value: str):
if not value.strip():
raise ValueError("Name cannot be empty")
self._name = value
# 属性装饰器 (deleter)
@name.deleter
def name(self):
print(f"Deleting name for {self._name}")
self._name = "Unnamed"
# 私有方法
def __calculate_age_in_days(self) -> int:
return self.__age * 365
# 魔术方法
def str(self) -> str:
return f"{self._species}: {self._name}"
def repr(self) -> str:
return f"{self.class.name}('{self._name}', {self.__age})"
def len(self) -> int:
return self.__age
def eq(self, other) -> bool:
if not isinstance(other, Animal):
return False
return self._name == other._name and self.age == other.age
# 2. 继承
class Mammal(Animal):
"""哺乳动物类"""
def init(self, name: str, age: int, fur_color: str):
super().init(name, age) # 调用父类构造函数
self._species = "Mammal"
self.fur_color = fur_color
self._offspring = []
def make_sound(self) -> str:
return "Some mammal sound"
# 方法重写
def get_info(self) -> str:
base_info = super().get_info()
return f"{base_info}, has {self.fur_color} fur"
# 多态性体现
def give_birth(self, baby_name: str):
baby = Mammal(baby_name, 0, self.fur_color)
self._offspring.append(baby)
return baby
def get_offspring_count(self) -> int:
return len(self._offspring)
# 3. 多重继承的混合类
class Swimmable:
"""可游泳的混合类"""
def swim(self) -> str:
return "Swimming in water"
class Flyable:
"""可飞行的混合类"""
def fly(self) -> str:
return "Flying in the sky"
# 4. 具体类 (多重继承)
class Bat(Mammal, Flyable):
"""蝙蝠类 - 继承哺乳动物且可飞行"""
def init(self, name: str, age: int, fur_color: str, wing_span: float):
Mammal.init(self, name, age, fur_color) # 显式调用父类初始化
self._species = "Bat"
self.wing_span = wing_span
def make_sound(self) -> str:
return "Squeak!"
# 方法重载的模拟 (Python不支持真正的方法重载)
def fly(self, height: Optional[float] = None) -> str:
if height:
return f"Flying at {height} meters with {self.wing_span}cm wingspan"
return super().fly()
# 5. 组合关系
class Zoo:
"""动物园类 - 展示组合关系"""
def init(self, name: str):
self.name = name
self.animals: List[Animal] = [] # 组合关系
def add_animal(self, animal: Animal):
if not Animal.is_animal(animal):
raise TypeError("Only animals can be added to the zoo")
self.animals.append(animal)
def remove_animal(self, animal: Animal):
if animal in self.animals:
self.animals.remove(animal)
def list_animals(self) -> List[str]:
return [str(animal) for animal in self.animals]
def make_all_sounds(self) -> List[str]:
return [animal.make_sound() for animal in self.animals]
def len(self) -> int:
return len(self.animals)
def contains(self, animal: Animal) -> bool:
return animal in self.animals
# 6. 数据类风格 (Python 3.7+)
from dataclasses import dataclass
@dataclass
class AnimalRecord:
"""动物记录数据类"""
name: str
species: str
age: int
weight: float
def to_json(self) -> str:
return json.dumps(self.dict)
# 演示使用
if name == "main":
# 创建对象
batman = Bat("Batman", 3, "black", 25.5)
print(batman.make_sound()) # 多态性
print(batman.fly(10)) # 方法重载模拟
print(batman.get_info()) # 继承的方法
# 属性装饰器使用
print(batman.name)
batman.name = "Bruce"
print(batman.name)
# 类方法和静态方法
print(f"Kingdom: {Animal.get_kingdom()}")
print(f"Is animal: {Animal.is_animal(batman)}")
# 组合关系演示
zoo = Zoo("City Zoo")
zoo.add_animal(batman)
# 创建更多动物
cat = Mammal("Whiskers", 2, "orange")
zoo.add_animal(cat)
print(f"Zoo has {len(zoo)} animals")
print(f"Animals: {zoo.list_animals()}")
print(f"Sounds: {zoo.make_all_sounds()}")
# 魔术方法演示
print(str(batman))
print(repr(batman))
print(f"Age in years: {len(batman)}")
# 数据类使用
record = AnimalRecord("Batman", "Bat", 3, 0.5)
print(record)
print(record.to_json())
# 私有方法和属性访问
try:
print(batman.__age) # 这会报错
except AttributeError as e:
print(f"Error accessing private attribute: {e}")
这个示例包含了 Python 面向对象编程的主要概念:
## 包含的概念:
类定义 – 使用 `class` 关键字
继承 – 单继承和多继承
多态 – 方法重写和抽象方法
封装 – 私有属性和方法
抽象基类 – 使用 `ABC` 和 `@abstractmethod`
类属性和实例属性
实例方法、类方法和静态方法
组合关系 – Zoo 类包含 Animal 对象
混合类 – 多重继承的用法
方法重写 – 子类重写父类方法
super() 函数 – 调用父类方法
类型提示 – 现代 Python 特性
数据类 – 使用 `@dataclass` 装饰器
这个示例展示了 Python 面向对象编程的完整特性集,可以作为学习参考。
属性装饰器 – `@property`, `@setter`, `@deleter`
访问控制机制
在 Python 中,虽然没有严格的访问控制机制,但通过命名约定来实现私有变量和受保护变量的概念。
- 私有变量使用双下划线 __ 作为前缀
- 受保护变量使用单下划线 _ 作为前缀
魔术方法
https://docs.python.org/3/reference/datamodel.html
__and__ __or__ __invert__ ...
装饰器 | Decorator
装饰器是种修改或增强函数/类行为的语法结构,本质上是个高阶函数,其接受函数作为参数,并返回函数。
1)基础:Decorators in Python – GeeksforGeeks
2)进阶:How to use Function Decorators in Python ? – GeeksforGeeks
Python Decorators Tutorial: What is a Decorator? | DataCamp
def uppercase_decorator(function):
def wrapper():
func_reture = function() # 调用原函数
make_uppercase = func_reture.upper() # 在原函数的基础上,进行其他修改
return make_uppercase
return wrapper # 返回被修改的函数
@uppercase_decorator
def say_hi():
return 'hello there'
print(say_hi()) # HELLO THERE
# 等价于
say_hi = uppercase_decorator(say_hi)
应用
单例模式 Singleton
模块本身就是天然的单例,因为模块在第一次导入时会执行初始化,后续导入都是返回同一个实例。
# ----------------------------------------------------------------------------- # singleton.py
class _Singleton:
def __init__(self):
self.value = None
def do_something(self):
print(f"Doing something with value: {self.value}")
instance = _Singleton()
# ----------------------------------------------------------------------------- # 在其他文件中使用
from singleton import instance
- 通过 new 的魔术方法
- 通过 Metaclass 创建
- ……
参考
DeepSeek / 给出一个 Python class 示例,该 class 需要包含 Python 面向对象的所有概念