之前在C++中学过一些类与对象的知识,Python也同样是面向对象的,因而也有类与对象
浅浅总结一下
总结Python中关于类的知识
文章目录
- [1 类的基本定义和访问](#1 类的基本定义和访问)
- [2 特殊变量(属性/方法)](#2 特殊变量(属性/方法))
-
- [2.1 双下划线开头结尾------特殊方法](#2.1 双下划线开头结尾——特殊方法)
-
- [2.1.1 初始化方法\init](#2.1.1 初始化方法_init_)
- [2.1.2 字符输出方法\str](#2.1.2 字符输出方法_str_)
- [2.1.3 调用方法\call](#2.1.3 调用方法_call_)
- [2.1.4 删除释放方法\init](#2.1.4 删除释放方法_init_)
- [2.2 双下滑线开头------私有属性和方法](#2.2 双下滑线开头——私有属性和方法)
- [2.3 类变量和实例变量](#2.3 类变量和实例变量)
- [3 继承](#3 继承)
- [4 多态](#4 多态)
-
- [4.1 鸭子类型 (Duck Typing)](#4.1 鸭子类型 (Duck Typing))
- [3.2 继承和方法重写](#3.2 继承和方法重写)
- [5 装饰器python](#5 装饰器python)
1 类的基本定义和访问
类的定义:
- 使用
class
关键字定义类。 - 类名通常采用首字母大写的驼峰命名法。
python
class MyClass:
pass
类内有属性 和方法(方法即函数)
-
类可以拥有属性,这些属性是类的一部分,可以是数据。
-
类可以定义方法,这些方法在类的对象上进行操作。
-
方法通常通过
self
参数访问对象的属性。
2 特殊变量(属性/方法)
2.1 双下划线开头结尾------特殊方法
2.1.1 初始化方法_init_
__init__
方法是类的构造器,用于创建对象时初始化对象。- 它的第一个参数总是
self
,代表当前实例。
python
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
2.1.2 字符输出方法_str_
- 定义了当使用 print() 函数或 str() 函数将实例转换为字符串时,返回的字符串表示形式。
- 目的是提供人类可读的字符串输出。
例子:
python
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person(name={self.name}, age={self.age})"
p = Person("Alice", 30)
print(p) # 输出: Person(name=Alice, age=30)
2.1.3 调用方法_call_
- 定义了当实例像函数一样被调用时 (例如 instance()) 所执行的操作。
- 可以用来实现函数对象、装饰器等功能。
例子:
python
class Counter:
def __init__(self):
self.count = 0
def __call__(self):
self.count += 1
return self.count
counter = Counter()
print(counter()) # 输出: 1
print(counter()) # 输出: 2
2.1.4 删除释放方法_init_
- 定义了当实例被垃圾回收时执行的操作,通常用于释放资源。
- 由于垃圾回收机制的复杂性,不建议过度依赖 del 方法。
例子:
python
class FileManager:
def __init__(self, filename):
self.file = open(filename, 'w')
def __del__(self):
self.file.close()
print("File closed")
fm = FileManager("temp.txt")
del fm # 输出: File closed
2.2 双下滑线开头------私有属性和方法
使用双下划线 __
前缀定义私有属性或方法,如 self.__private_var
。
2.3 类变量和实例变量
Python类变量和实例变量的区别
在Python中,类变量和实例变量是两种不同的变量类型,它们在定义位置、访问方式和生命周期方面存在差异:
1. 定义位置:
- 类变量: 在类内部,但在任何方法之外定义。它们由所有该类的实例共享。
- 实例变量: 在类的方法内部,使用 self 关键字定义。每个实例都有自己的一组实例变量。
2. 访问方式:
- 类变量: 可以通过类名或实例名访问。
- 实例变量: 只能通过实例名访问。
3. 生命周期:
- 类变量: 在类定义时创建,并在程序结束时销毁。
- 实例变量: 在实例创建时创建,并在实例销毁时销毁。
python
class Dog:
# 类变量
species = "Canis familiaris"
def __init__(self, name, age):
# 实例变量
self.name = name
self.age = age
# 访问类变量
print(Dog.species) # 输出: Canis familiaris
# 创建实例
buddy = Dog("Buddy", 3)
sparky = Dog("Sparky", 5)
# 访问实例变量
print(buddy.name) # 输出: Buddy
print(sparky.age) # 输出: 5
# 修改实例变量不会影响其他实例
buddy.age = 4
print(sparky.age) # 输出: 5 (sparky的age不受影响)
# 修改类变量会影响所有实例
Dog.species = "Canis lupus familiaris"
print(buddy.species) # 输出: Canis lupus familiaris
print(sparky.species) # 输出: Canis lupus familiaris
3 继承
- 类可以继承其他类的属性和方法,使用
class ChildClass(ParentClass)
。
python
class Animal:
pass
class Dog(Animal):
pass
4 多态
多态是面向对象编程的重要概念之一,它指的是同一个操作作用于不同的对象时,可以产生不同的行为。
Python中的多态主要体现在以下两个方面:
4.1 鸭子类型 (Duck Typing)
- Python崇尚"鸭子类型",即不在乎对象的类型,只在乎对象的行为。
- 如果一个对象"走路像鸭子,叫声像鸭子",那么它就可以被视为鸭子。
- 这意味着,只要对象实现了所需的方法,就可以将其用于任何期望该方法的地方,而无需考虑对象的具体类型。
例子:
python
class Dog:
def make_sound(self):
print("Woof!")
class Cat:
def make_sound(self):
print("Meow!")
def animal_sound(animal):
animal.make_sound()
animals = [Dog(), Cat()]
for animal in animals:
animal_sound(animal) # 无论是Dog还是Cat,都能调用make_sound方法
3.2 继承和方法重写
- 通过继承,子类可以继承父类的方法,并可以根据需要重写这些方法,实现不同的行为。
- 这种方式也体现了多态,因为同一个方法调用,根据对象类型的不同,执行的是不同的代码。
例子:
python
class Animal:
def speak(self):
print("Animal sound")
class Dog(Animal):
def speak(self):
print("Woof!")
class Cat(Animal):
def speak(self):
print("Meow!")
animals = [Animal(), Dog(), Cat()]
for animal in animals:
animal.speak() # 不同的动物发出不同的声音
多态的优点:
- 提高代码灵活性: 无需关注对象的具体类型,可以编写更通用的代码。
- 增强代码可扩展性: 更容易添加新的子类,而无需修改现有代码。
- 简化代码维护: 代码更加简洁,易于理解和维护。
5 装饰器python
装饰器本身是很大一块的知识
这些装饰器用于定义类中的特殊方法,它们在参数和行为方面有所不同
1. @staticmethod
- 定义静态方法。
- 静态方法不接收 self 或 cls 参数,它们与类本身无关,更像是普通的函数,只是碰巧在类中定义。
- 主要用于组织代码,将与类相关的函数归类到一起。
例子:
python
class MathUtils:
@staticmethod
def add(x, y):
return x + y
result = MathUtils.add(2, 3) # 无需创建实例,直接通过类名调用
print(result) # 输出: 5
2. @classmethod
- 定义类方法。
- 类方法接收 cls 参数,它代表类本身,而不是类的实例。
- 可以访问类变量和类方法,但不能访问实例变量。
- 常用于创建工厂方法,根据不同的参数创建不同的类实例。
例子:
python
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def from_birth_year(cls, name, birth_year):
age = 2023 - birth_year # 假设当前年份为2023
return cls(name, age)
person1 = Person("Alice", 30)
person2 = Person.from_birth_year("Bob", 1990)
print(person2.age) # 输出: 33
3. @property
- 定义属性。
- 将方法转换为属性,使得访问属性就像访问普通变量一样,但实际上是在调用方法。
- 可以用于添加属性的 getter、setter 和 deleter 方法,实现对属性访问的控制和验证。
例子:
python
class Celsius:
def __init__(self, temperature):
self._temperature = temperature
@property
def temperature(self):
return self._temperature
@temperature.setter
def temperature(self, value):
if value < -273.15:
raise ValueError("Temperature below -273.15 is not possible")
self._temperature = value
c = Celsius(0)
print(c.temperature) # 输出: 0
c.temperature = 37 # 自动调用setter方法
print(c.temperature) # 输出: 37
总结:
- @staticmethod: 定义静态方法,与类本身无关,类似于普通函数。
- @classmethod: 定义类方法,接收类作为参数,常用于工厂方法。
- @property: 定义属性,控制属性的访问方式,并可以添加 getter、setter 和 deleter 方法。
使用这些装饰器可以使代码更清晰、简洁,并实现更高级的功能。