「PYTHON」- 类和对象:面向对象编程中的基本概念,用于描述现实世界中的事物;

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 面向对象的所有概念