9. 面向对象编程
面向对象编程(OOP)是一种编程范式,使用“对象”来组织代码。对象是类的实例,类定义了对象的属性和方法。
类和对象
- 类是对象的蓝图或模板,定义了对象的属性和行为。
# 定义一个类
class Dog: # 相当于Dog(object)
# 初始化方法
def __init__(self, name, age):
self.name = name
self.age = age
# 实例方法
def bark(self):
print(f"{self.name} is barking")
# 创建对象(实例)
my_dog = Dog("Buddy", 3)
# 访问对象属性
print(my_dog.name) # 输出 "Buddy"
print(my_dog.age) # 输出 3
# 调用对象方法
my_dog.bark() # 输出 "Buddy is barking"
继承
- 继承是面向对象编程的一个重要特性,允许一个类继承另一个类的属性和方法。基类(父类)和派生类(子类)之间存在继承关系。
# 定义基类
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} is making a sound")
# 定义派生类
class Cat(Animal):
def __init__(self, name, color):
super().__init__(name)
self.color = color
def speak(self):
print(f"{self.name} is meowing")
# 创建派生类对象
my_cat = Cat("Whiskers", "white")
# 访问派生类对象属性和方法
print(my_cat.name) # 输出 "Whiskers"
print(my_cat.color) # 输出 "white"
my_cat.speak() # 输出 "Whiskers is meowing"
多态
多态是指不同类的对象可以通过相同的接口调用方法,产生不同的行为。通常通过方法重载实现。
# 示例代码
class Bird(Animal):
def speak(self):
print(f"{self.name} is chirping")
# 定义一个函数,接受一个动物对象
def animal_speak(animal):
animal.speak()
# 创建不同的动物对象
dog = Dog("Buddy", 3)
cat = Cat("Whiskers", "white")
bird = Bird("Tweety")
# 调用函数
animal_speak(dog) # 输出 "Buddy is barking"
animal_speak(cat) # 输出 "Whiskers is meowing"
animal_speak(bird) # 输出 "Tweety is chirping"
封装
封装是指将对象的属性和方法私有化,保护对象的内部状态不被外部直接访问和修改。通过定义公有和私有方法和属性实现封装。
# 示例代码
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.__balance = balance # 私有属性
def deposit(self, amount):
if amount > 0:
self.__balance += amount
else:
print("存款金额必须大于零")
def withdraw(self, amount):
if amount <= self.__balance:
self.__balance -= amount
else:
print("余额不足")
def get_balance(self):
return self.__balance
# 创建对象
account = BankAccount("Alice", 1000)
# 访问公有属性和方法
print(account.owner) # 输出 "Alice"
account.deposit(500)
account.withdraw(200)
print(account.get_balance()) # 输出 1300
# 试图访问私有属性(会报错)
# print(account.__balance)
通过掌握面向对象编程的基本概念和技巧,你可以编写更具结构化、可扩展性和可维护性的代码。
私有属性
在面向对象编程中,让类属性能够被直接访问是危险的。使用私有属性可以保证属性不能被直接访问修改,增强安全性。私有属性用__
(双下划线)前缀进行标识。
#-- coding:UTF-8 --
# 定义一个类
class Dog:
# 初始化方法
def __init__(self, name, age):
self.name = name
self.__age = age # __age为私有属性
# 创建对象(实例)
my_dog = Dog("Buddy", 3)
# 访问对象属性
print(my_dog.name) # 输出 "Buddy"
#print(my_dog.__age) # 无法访问
# 强制访问私有属性
print(my_dog._Dog__age)
10. 高级主题
装饰器
- 装饰器是一种用于修改或增强函数行为的高级技术。它本质上是一个函数,接受一个函数作为参数,并返回一个新的函数。
# 定义装饰器
def my_decorator(func):
def wrapper():
print("在函数执行之前")
func()
print("在函数执行之后")
return wrapper
# 使用装饰器
@my_decorator
def say_hello():
print("Hello!")
say_hello()
-
在这个示例中,
my_decorator
装饰器在say_hello
函数的执行前后添加了额外的打印语句。 -
装饰器可以接受参数,以提供更灵活的功能。
# 定义带参数的装饰器
def repeat(num_times):
def decorator_repeat(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
func(*args, **kwargs)
return wrapper
return decorator_repeat
@repeat(num_times=3)
def say_hello(name):
print(f"Hello, {name}!")
say_hello("Alice")
- 在这个示例中,
repeat
装饰器接受参数num_times
,并重复执行say_hello
函数指定的次数。
生成器
- 生成器是一种特殊的迭代器,使用
yield
关键字生成值。与普通函数不同,生成器在每次生成值后暂停,并在下次调用时继续执行。
# 定义生成器
def count_up_to(max):
count = 1
while count <= max:
yield count
count += 1
# 使用生成器
counter = count_up_to(5)
for num in counter:
print(num)
- 在这个示例中,
count_up_to
生成器每次生成一个数值,并在达到max
值时停止。
高阶生成器
- 生成器可以与其他生成器组合使用,以创建复杂的数据处理管道。
def generator1():
yield from range(3)
def generator2():
yield from range(3, 6)
# 组合生成器
def combined_generator():
yield from generator1()
yield from generator2()
for value in combined_generator():
print(value)
Lambda函数
- Lambda函数是一种简洁的匿名函数,用于定义简单的函数。常用于需要一个短期函数的场景。
# 示例代码
add = lambda x, y: x + y
print(add(3, 5)) # 输出 8
列表推导式
- 列表推导式是一种创建列表的简洁方法,可以在一行代码中生成列表。
# 示例代码
squares = [x**2 for x in range(10)]
print(squares) # 输出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
面向对象编程的高级特性
- 包括类方法、静态方法和属性装饰器等。
# 示例代码
class MyClass:
class_variable = "I am a class variable"
def __init__(self, instance_variable):
self.instance_variable = instance_variable
@classmethod # 类方法
def class_method(cls):
return cls.class_variable
@staticmethod # 静态方法
def static_method():
return "I am a static method"
@property # 属性装饰器
def instance_property(self):
return self.instance_variable
obj = MyClass("I am an instance variable")
print(MyClass.class_method()) # 输出 "I am a class variable"
print(MyClass.static_method()) # 输出 "I am a static method"
print(obj.instance_property) # 输出 "I am an instance variable"
1. 类方法(Class Method)
类方法使用 @classmethod
装饰器定义,第一个参数是类本身,通常命名为 cls
。类方法可以访问类变量和修改类状态。
class MyClass:
class_variable = "I am a class variable"
def __init__(self, instance_variable):
self.instance_variable = instance_variable
@classmethod
def class_method(cls):
return cls.class_variable
# 使用类方法
print(MyClass.class_method()) # 输出 "I am a class variable"
在这个示例中,class_method
是一个类方法,它返回类变量 class_variable
的值。
2. 静态方法(Static Method)
静态方法使用 @staticmethod
装饰器定义,不需要传入类或实例作为参数。静态方法通常用于执行一些逻辑操作,这些操作与类和实例无关。
class MyClass:
@staticmethod
def static_method():
return "I am a static method"
# 使用静态方法
print(MyClass.static_method()) # 输出 "I am a static method"
在这个示例中,static_method
是一个静态方法,它不访问类或实例的数据,仅执行独立的逻辑。
3. 属性装饰器(Property Decorator)
属性装饰器 @property
允许你将类的方法转换为只读属性,使得你可以像访问属性一样访问方法。这使得类的设计更直观和易于使用。
1. 基本用法
使用 @property
可以定义一个只读属性。
class Circle:
def __init__(self, radius):
self._radius = radius
@property # 将方法转换为属性
def radius(self):
return self._radius
# 创建对象并访问属性
c = Circle(5)
print(c.radius) # 输出 5
在这个示例中,radius
方法被转换为一个只读属性,因此你可以像访问属性一样访问它,而不需要调用方法。
2. 设置器(Setter)
除了只读属性,属性装饰器还可以定义属性的设置器,允许你在设置属性值时执行一些额外的逻辑。使用 @<property_name>.setter
装饰器来定义设置器。
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter # 定义设置器
def radius(self, value):
if value < 0:
raise ValueError("半径不能为负数")
self._radius = value
# 创建对象并设置属性
c = Circle(5)
print(c.radius) # 输出 5
c.radius = 10
print(c.radius) # 输出 10
# c.radius = -1 # 会引发 ValueError: 半径不能为负数
在这个示例中,radius
属性有一个设置器,当尝试设置负值时会引发异常。
3. 删除器(Deleter)
同样地,你还可以定义属性的删除器,使用 @<property_name>.deleter
装饰器来定义删除器。
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("半径不能为负数")
self._radius = value
@radius.deleter # 定义删除器
def radius(self):
print("删除半径属性")
del self._radius
# 创建对象并删除属性
c = Circle(5)
print(c.radius) # 输出 5
del c.radius
# print(c.radius) # 会引发 AttributeError: 'Circle' object has no attribute '_radius'
在这个示例中,radius
属性有一个删除器,当属性被删除时会执行特定的逻辑。
4. 完整示例
一个包含所有三种方法的完整示例如下:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("半径不能为负数")
self._radius = value
@radius.deleter
def radius(self):
print("删除半径属性")
del self._radius
# 使用属性装饰器
c = Circle(5)
print(c.radius) # 输出 5
c.radius = 10
print(c.radius) # 输出 10
del c.radius
通过使用属性装饰器,你可以使类的接口更加直观和易于使用,同时能够控制属性的访问和修改。
11. 数据科学与机器学习库
1. NumPy
NumPy 是一个用于科学计算的库,支持多维数组和矩阵运算,提供了大量的数学函数。
import numpy as np
# 创建数组
array = np.array([1, 2, 3, 4, 5])
print(array)
# 数组运算
print(array + 10)
print(array * 2)
2. pandas
pandas 是一个数据分析和处理库,提供了高性能的数据结构和数据分析工具。
import pandas as pd
# 创建数据框
data = {'Name': ['Alice', 'Bob', 'Charlie'], 'Age': [25, 30, 35]}
df = pd.DataFrame(data)
print(df)
# 数据框操作
print(df['Name'])
print(df.describe())
3. matplotlib
matplotlib 是一个绘图库,用于创建静态、动态和交互式的图表。
import matplotlib.pyplot as plt
# 创建数据
x = [1, 2, 3, 4, 5]
y = [2, 3, 5, 7, 11]
# 绘制折线图
plt.plot(x, y)
plt.xlabel('x轴')
plt.ylabel('y轴')
plt.title('折线图示例')
plt.show()
4. scikit-learn
scikit-learn 是一个用于机器学习的库,提供了简单高效的数据挖掘和数据分析工具。
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# 加载数据集
iris = datasets.load_iris()
X = iris.data
y = iris.target
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建并训练模型
model = LogisticRegression()
model.fit(X_train, y_train)
# 预测并评估模型
y_pred = model.predict(X_test)
print(f"准确率: {accuracy_score(y_test, y_pred)}")
12. 高级主题
装饰器
- 装饰器是一种用于修改或增强函数行为的高级技术。它本质上是一个函数,接受一个函数作为参数,并返回一个新的函数。
# 定义装饰器
def my_decorator(func):
def wrapper():
print("在函数执行之前")
func()
print("在函数执行之后")
return wrapper
# 使用装饰器
@my_decorator
def say_hello():
print("Hello!")
say_hello()
-
在这个示例中,
my_decorator
装饰器在say_hello
函数的执行前后添加了额外的打印语句。 -
装饰器可以接受参数,以提供更灵活的功能。
# 定义带参数的装饰器
def repeat(num_times):
def decorator_repeat(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
func(*args, **kwargs)
return wrapper
return decorator_repeat
@repeat(num_times=3)
def say_hello(name):
print(f"Hello, {name}!")
say_hello("Alice")
- 在这个示例中,
repeat
装饰器接受参数num_times
,并重复执行say_hello
函数指定的次数。
生成器
- 生成器是一种特殊的迭代器,使用
yield
关键字生成值。与普通函数不同,生成器在每次生成值后暂停,并在下次调用时继续执行。
# 定义生成器
def count_up_to(max):
count = 1
while count <= max:
yield count
count += 1
# 使用生成器
counter = count_up_to(5)
for num in counter:
print(num)
- 在这个示例中,
count_up_to
生成器每次生成一个数值,并在达到max
值时停止。
高阶生成器
- 生成器可以与其他生成器组合使用,以创建复杂的数据处理管道。
def generator1():
yield from range(3)
def generator2():
yield from range(3, 6)
# 组合生成器
def combined_generator():
yield from generator1()
yield from generator2()
for value in combined_generator():
print(value)
Lambda函数
- Lambda函数是一种简洁的匿名函数,用于定义简单的函数。常用于需要一个短期函数的场景。
# 示例代码
add = lambda x, y: x + y
print(add(3, 5)) # 输出 8
列表推导式
- 列表推导式是一种创建列表的简洁方法,可以在一行代码中生成列表。
# 示例代码
squares = [x**2 for x in range(10)]
print(squares) # 输出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
面向对象编程的高级特性
- 包括类方法、静态方法和属性装饰器等。
# 示例代码
class MyClass:
class_variable = "I am a class variable"
def __init__(self, instance_variable):
self.instance_variable = instance_variable
@classmethod # 类方法
def class_method(cls):
return cls.class_variable
@staticmethod # 静态方法
def static_method():
return "I am a static method"
@property # 属性装饰器
def instance_property(self):
return self.instance_variable
obj = MyClass("I am an instance variable")
print(MyClass.class_method()) # 输出 "I am a class variable"
print(MyClass.static_method()) # 输出 "I am a static method"
print(obj.instance_property) # 输出 "I am an instance variable"
1. 类方法(Class Method)
类方法使用 @classmethod
装饰器定义,第一个参数是类本身,通常命名为 cls
。类方法可以访问类变量和修改类状态。
class MyClass:
class_variable = "I am a class variable"
def __init__(self, instance_variable):
self.instance_variable = instance_variable
@classmethod
def class_method(cls):
return cls.class_variable
# 使用类方法
print(MyClass.class_method()) # 输出 "I am a class variable"
在这个示例中,class_method
是一个类方法,它返回类变量 class_variable
的值。
2. 静态方法(Static Method)
静态方法使用 @staticmethod
装饰器定义,不需要传入类或实例作为参数。静态方法通常用于执行一些逻辑操作,这些操作与类和实例无关。
class MyClass:
@staticmethod
def static_method():
return "I am a static method"
# 使用静态方法
print(MyClass.static_method()) # 输出 "I am a static method"
在这个示例中,static_method
是一个静态方法,它不访问类或实例的数据,仅执行独立的逻辑。
3. 属性装饰器(Property Decorator)
属性装饰器 @property
允许你将类的方法转换为只读属性,使得你可以像访问属性一样访问方法。这使得类的设计更直观和易于使用。
1. 基本用法
使用 @property
可以定义一个只读属性。
class Circle:
def __init__(self, radius):
self._radius = radius
@property # 将方法转换为属性
def radius(self):
return self._radius
# 创建对象并访问属性
c = Circle(5)
print(c.radius) # 输出 5
在这个示例中,radius
方法被转换为一个只读属性,因此你可以像访问属性一样访问它,而不需要调用方法。
2. 设置器(Setter)
除了只读属性,属性装饰器还可以定义属性的设置器,允许你在设置属性值时执行一些额外的逻辑。使用 @<property_name>.setter
装饰器来定义设置器。
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter # 定义设置器
def radius(self, value):
if value < 0:
raise ValueError("半径不能为负数")
self._radius = value
# 创建对象并设置属性
c = Circle(5)
print(c.radius) # 输出 5
c.radius = 10
print(c.radius) # 输出 10
# c.radius = -1 # 会引发 ValueError: 半径不能为负数
在这个示例中,radius
属性有一个设置器,当尝试设置负值时会引发异常。
3. 删除器(Deleter)
同样地,你还可以定义属性的删除器,使用 @<property_name>.deleter
装饰器来定义删除器。
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("半径不能为负数")
self._radius = value
@radius.deleter # 定义删除器
def radius(self):
print("删除半径属性")
del self._radius
# 创建对象并删除属性
c = Circle(5)
print(c.radius) # 输出 5
del c.radius
# print(c.radius) # 会引发 AttributeError: 'Circle' object has no attribute '_radius'
在这个示例中,radius
属性有一个删除器,当属性被删除时会执行特定的逻辑。
4. 完整示例
一个包含所有三种方法的完整示例如下:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("半径不能为负数")
self._radius = value
@radius.deleter
def radius(self):
print("删除半径属性")
del self._radius
# 使用属性装饰器
c = Circle(5)
print(c.radius) # 输出 5
c.radius = 10
print(c.radius) # 输出 10
del c.radius
通过使用属性装饰器,你可以使类的接口更加直观和易于使用,同时能够控制属性的访问和修改。