一.AI&Python基础语法
1️⃣AI&Python数据类型(上)
2️⃣AI&Python数据类型(下)
3️⃣AI&Python逻辑判断与循环
4️⃣AI&Python函数的应用
面向对象编程(OOP),本质上是借助类与对象对代码进行有序的组织与管理。打个比方,你可以把类看作是一份详细的菜谱,里面写明了所需的各种食材、调料以及烹饪步骤。而对象就像是按照这份菜谱,在厨房中实际操作的一口锅,通过这口锅,利用菜谱里的信息,将食材一步步转化为美味佳肴。在编程中,我们把相关功能的代码封装在类里,再基于类创建出一个个对象,从而让这些代码得以实际运用。
类是对象的构建蓝图。不妨设想,类如同工厂里精细绘制的设计图,这张图上清晰标注了制造特定对象的所有规格与流程。而对象,则是依据这张详尽设计图在生产线上诞生的实体产品。
用更通俗的话语来讲,类就像是一个标准化的模板,而对象便是套用这个模板制造出来的具体实例。举例来说,如果我们计划构建一个名为“车”的类,在这个类里,详细定义了车所具备的各种属性,诸如颜色、品牌、型号,以及车能执行的各类方法,像行驶、加速、刹车等。完成类的定义后,便能依据这个“车”类,创建出形形色色的车对象,比如一辆豪华的宝马,或是一辆科技感十足的小米SU7。
2.1定义一个类
类的定义可以非常简单地理解为一种创建对象的蓝图或模板。它定义了对象应该具有的属性(特征)和方法(行为)。在面向对象编程中,类是构建程序的基本单元之一。
【实例36】定义一个智能手机的类。
#定义一个智能手机的类class Smartphone: #类的构造函数,用于初始化对象 def __init__(self, make, model): self.make = make # 手机品牌 self.model = model # 手机型号 def make_call(self): print(f"正在使用{self.make}{self.model}手机!")# 实例化:根据类创建对象my_phone = Smartphone("Apple","iPhone 17 Pro Max")# 使用对象的方法my_phone.make_call()
【分析解答】
__init__是构造函数,用于初始化对象的属性。
self代表当前对象本身,是对象自己的“代名词”,不加它会遇到“undefined”的错误。
my_phone是一个对象,是 Smartphone 类的实例。
输出结果:
2.2类变量与实例变量
类变量是所有对象共享的。实例变量是每个对象独有的。
【实例37】定义一个智能手机的类,区分类变量和实例变量。
#定义一个智能手机的类class Smartphone: hardware ="屏幕,电池" # 类变量,所有车共享的 def __init__(self, make, model): self.make = make # 实例变量 self.model = model # 实例变量# 创建两个车对象phone1 = Smartphone("小米","17 pro")phone2 = Smartphone("华为","Mate XTs")# 访问类变量print("访问类变量phone1:",phone1.hardware)print("访问类变量phone2:",phone2.hardware)# 访问实例变量print("访问实例变量phone1的品牌型号:",phone1.make, phone1.model)print("访问实例变量phone2的品牌型号:",phone2.make, phone2.model)
【分析解答】
Hardware是类变量,不管你创造什么手机,它始终都有屏幕和电池。
make和 model 是实例变量,每个手机对象都有自己的品牌和型号。
换个简单说法,类变量是“全公司共享”,实例变量是“每个员工自己独有”。
输出结果:
2.3实例、类与静态方法
实例方法:实例方法是与类的实例(即对象)紧密关联的函数。它们需要通过类的实例来调用,并且通常用于操作或访问该实例的特定数据(即实例属性)。实例方法能够访问并修改实例的状态,是面向对象编程中实现对象行为的主要手段。
类方法:类方法则不同,它们与类本身相关联,而不是与类的某个具体实例相关联。因此,类方法需要通过类本身来调用,而不是通过类的实例。类方法主要用于操作那些与类本身相关而不是与任何特定实例相关的数据(即类属性)。类方法可以通过@classmethod装饰器来定义,并且它们的第一个参数通常是cls,用于指代调用该方法的类。
静态方法:静态方法是另一种特殊的方法,它既不与类的实例相关联,也不与类本身直接相关。静态方法主要用于定义一些工具性质的函数,这些函数可能位于某个类的命名空间中,但实际上它们并不需要访问或修改类的任何状态(无论是实例状态还是类状态)。静态方法可以通过@staticmethod装饰器来定义,它们可以像普通函数一样被调用,但它们在类的命名空间中提供了更好的组织性和封装性。静态方法的调用既不需要类的实例,也不需要类本身作为前缀,但它们仍然可以通过类的实例或类名来调用。
【实例38】定义一个智能手机的类,分别测试实例方法、类方法与静态方法。
class Smartphone: hardware = "屏幕,电池" # 类变量,所有车共享的 def __init__(self, make, model): self.make = make # 实例变量 self.model = model # 实例变量 # 实例方法 def display_info(self): return f"品牌: {self.make}, 型号: {self.model}" # 类方法 @classmethod def change_hardware(cls, new_hardware): cls.hardware = new_hardware # 静态方法 @staticmethod def is_smartphone(make): # 假设只有"Apple", "Samsung", "Huawei" ,"Xiaomi" 是智能手机品牌 smartphone_brands = ["Apple", "Samsung", "Huawei","Xiaomi"] return make in smartphone_brands# 测试实例方法phone = Smartphone("Apple", "iPhone 17")print("测试实例方法:",phone.display_info())# 测试类方法Smartphone.change_hardware("屏幕,电池,摄像头")print("测试类方法:",Smartphone.hardware)# 测试静态方法print("测试静态方法品牌苹果:",Smartphone.is_smartphone("Apple"))print("测试静态方法品牌诺基亚:",Smartphone.is_smartphone("Nokia"))
【分析解答】
实例方法(display_info):这个方法用于显示智能手机的品牌和型号。它通过self访问实例变量make和model。
类方法(change_hardware):使用@classmethod装饰器定义。这个方法用于更改类变量hardware。它通过cls参数访问类变量。
静态方法(is_smartphone):使用@staticmethod装饰器定义。这个方法用于判断一个品牌是否是智能手机品牌。它不访问类变量或实例变量,因此不需要self或cls参数。
输出结果:
3.1继承
继承是面向对象编程(OOP)的基石之一,它允许我们定义一个新类时基于一个或多个已存在的类。这些已存在的类被称为父类、基类或超类,而新的类则被称为子类、派生类或衍生类。通过继承机制,子类自动获取(或继承)了父类的数据属性和行为方法,并且可以在不改变父类的前提下扩展额外的功能或者修改已有功能。
在Python中,要创建一个继承自另一个类的新类,只需要在定义新类时将父类的名字放在类名后的括号内。
【实例39】创建一个简单智能手机类,在此基础上定义一个高级智能手机的类,可以继承复用前面的简单智能手机类。
# 定义一个简单智能手机类class Smartphone: def __init__(self, make, model): self.make = make # 手机品牌 self.model = model # 手机型号 # 实例方法:显示手机信息 def display_info(self): return f"品牌: {self.make}, 型号: {self.model}"# 定义一个高级智能手机类,它继承自Smartphoneclass AdvancedSmartphone(Smartphone): def __init__(self, make, model, os_version): super().__init__(make, model) # 使用super()调用父类的构造函数 self.os_version = os_version # 新增属性:操作系统版本 # 添加新的实例方法:更新操作系统 def update_os(self, new_version): self.os_version = new_version return f"{self.make}{self.model} 的操作系统已更新到版本 {self.os_version}" # 覆盖父类的display_info方法以显示更多信息 def display_info(self): base_info = super().display_info() # 调用父类的方法获取基本信息 return f"{base_info}, 操作系统: {self.os_version}"# 创建Smartphone实例并测试print("------创建Smartphone实例并测试------")simple_phone = Smartphone("Apple", "iPhone 17")print(simple_phone.display_info())# 创建AdvancedSmartphone实例并测试print("------创建AdvancedSmartphone实例并测试------")advanced_phone = AdvancedSmartphone("Samsung", "S25 FE", "Android 16")print(advanced_phone.display_info())print(advanced_phone.update_os("Android 17"))
【分析解答】本实例展示了继承的核心思想:AdvancedSmartphone类从Smartphone类继承而来,并且添加了额外的功能(如操作系统版本和更新操作系统的方法)。同时,我们还重写了display_info方法以提供更详细的信息。这样,我们就能够创建具有不同特性的对象,而无需重复编写相同的代码。
输出结果:
3.2封装
Python中的封装是面向对象编程的一个核心概念,它指的是将数据(属性)和操作这些数据的方法(函数)捆绑在一起,形成一个独立的单元(即类)。封装隐藏了对象的属性和实现细节,仅对外公开接口(即方法),使得外部代码无法直接访问对象的内部状态,只能通过特定的方法来进行操作。这样做的好处包括提高了代码的安全性、降低了模块间的耦合度,并增强了代码的复用性。
在Python中,我们使用单下划线_前缀来表示私有属性或方法,这表示它们不应该被类的外部直接访问。在Python中,封装主要是指把数据(属性)和操作这些数据的函数(方法)包装在类的内部。为了不让外部代码轻易地改变这些数据,我们会限制对这些属性的直接访问。通常,我们会将不想被外部直接访问的属性或方法命名为以单下划线_开头,这表示“这是内部使用的,请勿直接访问”。
例如,如果你有一个Person类,并且你不希望外部代码直接修改人的年龄,你可以将年龄定义为_age。然后,你可以提供一些方法,比如get_age()和set_age(new_age),让外部代码通过这些方法来获取或设置年龄,而不是直接访问_age属性。
简而言之,在Python中,封装就是通过类隐藏数据的具体实现,只暴露安全的操作接口给外界使用。
【实例40】定义一个简单智能手机类,再定义一个智能相机继承,封装相机像素等基础信息。
# 定义一个简单智能手机类class Smartphone: def __init__(self, make, model): self._make = make # 私有属性:品牌 self._model = model # 私有属性:型号 def display_info(self): return f"品牌: {self._make}, 型号: {self._model}"class CameraPhone(Smartphone): def __init__(self, make, model, megapixels): super().__init__(make, model) # 继承父类的构造函数 self._megapixels = megapixels # 新增私有属性:相机像素 def display_info(self): # 扩展父类的方法,添加相机信息 base_info = super().display_info() return f"{base_info}, 相机像素: {self._megapixels} 万像素" def take_photo(self): # 封装拍照的行为 print(f"使用 {self._megapixels} 万像素的相机拍照")# 使用继承和封装print("------继承------")camera_phone = CameraPhone("小米", "Mi 17", '3*5000')print(camera_phone.display_info())print("------封装------")camera_phone.take_photo()
【分析解答】
Smartphone类定义了两个私有属性_make和_model以及一个方法display_info。
CameraPhone类继承自Smartphone,并新增了一个私有属性_megapixels来表示相机的像素。
CameraPhone的display_info方法重写了父类的方法,以包含额外的相机信息。
CameraPhone还定义了一个新方法take_photo,它模拟了拍照的行为,展示了如何通过封装来隐藏实现细节。
单下划线_前缀用于表示这些属性是私有的,意味着它们不应该直接从类外部访问,这是Python中的一种封装方式。
输出结果:
3.3多态
在Python编程语言里,多态性体现了一种灵活且强大的机制,它让程序员可以通过一个统一的接口来处理来自不同类别的对象。这种能力的核心在于,即便调用的是相同的方法,实际执行的动作也会依据运行时对象的具体类型(即所属的类,可能是基础类或是派生类)而动态变化。这样的设计思路不仅增强了代码的灵活性和可复用性,还推动了模块化开发,简化了系统的扩展与维护工作。简单来说,Python中的多态实现了“单一接口,多样实现”的理念,有助于复杂应用的构建和管理。通常情况下,在Python中是通过子类继承自父类并覆盖(重写)父类的方法来达成多态效果的。
【实例41】定义一个宠物店的类,其中包含不同种类的宠物,每个宠物都有自己的特性。在此基础上,通过多态性来展示如何用统一的方式处理不同的宠物。
class Pet: def __init__(self, name): self.name = name def speak(self): # 提供一个默认行为,所有宠物都能发出声音。 return "这只宠物发出了声音"class Dog(Pet): def speak(self): # 重写父类方法,提供狗特有的发声方式。 return f"{self.name}说:汪!汪!"class Cat(Pet): def speak(self): # 重写父类方法,提供猫特有的发声方式。 return f"{self.name}说:喵...喵..."class Parrot(Pet): def speak(self): # 重写父类方法,提供鹦鹉特有的发声方式。 return f"{self.name}说:你好!你好!"def pet_shop_service(pet): # 假定宠物店的服务员不知道具体是哪种宠物, # 但是知道所有的宠物都有发声的方法。 print(f"服务员说:欢迎光临,这是{type(pet).__name__} {pet.name};{pet.speak()}")# 使用多态dog = Dog("小狗-球球")cat = Cat("小猫-小黑")parrot = Parrot("小鹦鹉-彩虹")# 不管是狗、猫还是鹦鹉,都可以通过同一个接口调用发声方法。pet_shop_service(dog)pet_shop_service(cat)pet_shop_service(parrot)
【分析解答】本实例中,Pet类作为所有宠物的基础,为每只宠物提供了一个名字属性name和一个通用的speak方法。每个具体的宠物类型(如Dog、Cat和Parrot)都继承自Pet并实现了自己的speak方法,这些方法返回了各自动物特有的叫声,并包含了宠物的名字。当宠物店的店员接待顾客时,他并不需要知道面前的具体是什么类型的宠物,只需要调用speak方法就可以得到该宠物的叫声以及它的名字。这体现了多态性的优势:代码更加简洁和易于扩展。如果将来有新的宠物加入宠物店,只要新宠物类继承自Pet并实现了speak方法,那么pet_shop_service函数就可以处理这个新宠物,而无需修改现有代码。
输出结果:
3.4特殊方法
特殊方法,亦被称为魔术方法或双下划线方法,在Python编程语言中具有重要作用。这些方法利用了特定的命名规则——即方法名称前后带有双下划线(例如:init、__str__等),为类提供了一种机制,使其能够与Python的内置功能、函数以及协议实现自然的交互。
通过定义这些特殊方法,我们可以指定当一个类的实例参与某些操作时应表现出的行为,比如数学运算、比较、迭代或者转换成字符串形式等。这不仅使得类可以更深入地融入Python的内部工作机制和协议之中,而且有助于提高代码的清晰度和维护性,同时彰显了Python的高度灵活性和可扩展性。具体来说:
【实例42】创建一个书Book类,并定义几个特殊方法,以展示对应功能。
class Book: def __init__(self, title, author, pages, words): # 初始化方法,用于设置对象的初始状态 self.title = title self.author = author self.pages = pages self.words= words def __str__(self): # 定义对象的字符串表示形式,通常用于用户友好的输出 return f'《{self.title}》作者为 {self.author}, 合计{self.pages}页, {self.words}万字' def __repr__(self): # 定义对象的另一种表现形式 return f"书名'{self.title}', 作者为'{self.author}', 合计{self.pages}页, {self.words}万字" def __eq__(self, other): # 定义两个书籍对象相等的条件 if isinstance(other, Book): return (self.title == other.title and self.author == other.author and self.pages == other.pages and self.words == other.words) return False# 创建两个Book实例book1 = Book("Python金融量化实战:固定收益类产品分析", "欧晨", 284,41.2)book2 = Book("Python金融量化实战:固定收益类产品分析", "欧晨", 284,41.2)print("------使用__str__方法打印书本信息------")print(book1)print("------使用__repr__方法打印本书信息------")print(repr(book1))print("------使用__eq__方法比较两个书籍对象是否相等------")print(book1 == book2)
【分析解答】
__init__方法初始化了每个Book实例的状态。
__str__方法提供了一个易读的字符串表示,当调用print()函数或在交互式解释器中直接查看对象时会使用这个方法。
__repr__方法提供了更正式的字符串表示,旨在尽可能准确地反映对象的信息,通常用于调试和开发环境中。
__eq__方法允许我们比较两个Book对象是否相等,这里我们定义了如果两个Book对象有相同的标题、作者、页数以及字数,则认为它们是相等的。
输出结果:
本章小结
本章涵盖了Python基础语法的全面介绍,包括数据类型(如数字、字符串、列表等)、逻辑控制结构(判断与循环)、函数的应用(定义、参数、作用域等),以及面向对象编程的基本概念(类、继承、多态性)。这些知识为编写结构良好、可维护性强的代码提供了理论基础。