摘要:Python 是一种多功能编程语言,支持多种编程范式,包括面向对象编程 (OOP)和过程编程。这种灵活性使开发人员能够根据项目的特定需求选择最合适的范例,结合每种方法的优势以实现最佳结果。
Python 是一种多功能编程语言,支持多种编程范式,包括面向对象编程 (OOP) 和过程编程。这种灵活性使开发人员能够根据项目的特定需求选择最合适的范例,结合每种方法的优势以实现最佳结果。
过程编程基于过程调用的概念。它像配方一样构建程序,因为它以函数和代码块的形式提供了一组步骤,这些步骤按顺序流动以完成任务。此范例对于可以通过一系列过程步骤完成的简单任务特别有用,使代码易于理解和调试。
面向对象编程 (OOP) 是一种使用对象和类来构建软件程序的编程范例。它强调将对数据进行操作的数据(属性)和行为(方法)捆绑到称为对象的各个单元中。这种方法有利于对真实世界的实体进行建模,促进代码重用,并促进复杂软件系统的开发。
换句话说,OOP 是一种围绕数据或对象而不是函数和逻辑组织软件设计的范式。对象可以定义为具有唯一属性和行为的数据字段。Python 对 OOP 的支持非常广泛,允许开发人员实现类、继承、多态性和封装,从而更轻松地创建复杂、可重用和模块化的代码,这些代码可以模拟真实场景。
在 OOP 和过程编程之间进行选择取决于各种因素,包括应用程序的复杂性、团队偏好以及正在开发的软件的特定要求。
通常,OOP 更适合具有复杂数据模型和行为的应用程序,需要可重用和模块化的代码。
另一方面,过程编程可能更适合于更简单的、基于任务的脚本,其中执行简单的操作序列。
在 OOP 中,类是创建对象的蓝图。它定义了类的已创建对象将具有的一组属性和方法。类提供了一种将数据和功能捆绑在一起的方法。
Python 中的类可以看作是工业环境中的图章。想象一下,你有一枚图章,旨在产生特定的形状或图案——这枚图章就是你的类。每次将图章按压到材质上时,都会创建由图章定义的形状或图案的精确复制品。这些副本类似于 Python 中的对象。
正如 stamp 封装了设计细节并且可以重复用于生成多个副本(对象)一样,类封装了数据(属性)和行为(方法),并且可以多次实例化以创建多个对象。
每个对象都是一个唯一的实例,其属性中可以保存不同的值,类似于可以在不同的材料或不同的颜色上制作每个图章印记,但所有印记都共享相同的底层设计。
在 Python 中创建类非常简单明了:
class MyClass: # Class attribute attribute = "This is a class attribute." # Initializer / Instance attributes def __init__(self, value): self.instance_attribute = value # Method def my_method(self): return f"My instance attribute is: {self.instance_attribute}"在此示例中,MyClass 具有类属性属性、设置实例属性的初始值设定项方法__init__和对实例属性进行操作的方法 my_method。
每个对象的属性可以具有不同的值,以区别于同一类的其他对象(请记住 stamp 示例)。
创建对象就像调用类一样简单:
my_object = MyClass("Hello, Object!")print(my_object.instance_attribute) # Accessing an instance attributeprint(my_object.my_method) # Calling a method on the objectoo在面向对象编程 (OOP) 中,属性是属于类或类实例的变量。它们表示对象的属性或特征,有助于将其与其他对象区分开来。属性用于存储有关对象的信息,并且可以在对象的生命周期内访问或修改它们。
OOP 中的属性主要有两种类型:类属性和实例属性。
类属性是在类的所有实例之间共享的变量。它们属于类本身,不属于任何单个实例。这意味着,如果更改 class 属性的值,则更改将反映在该类的所有实例中。类 atrribute 示例:
class Dog: species = "Canis familiaris" # Class attribute def __init__(self, name, age): self.name = name # Instance attribute self.age = age # Instance attribute# Accessing a class attributeprint(Dog.species) # Output: Canis familiaris# Class attributes are shared by all instancesdog1 = Dog("Buddy", 5)dog2 = Dog("Molly", 3)print(dog1.species) # Output: Canis familiarisprint(dog2.species) # Output: Canis familiaris类属性的一个主要应用是定义与类相关的全局常量。例如,考虑一个场景,您正在创建一个类来表示不同的形状。在 Circle 类中,您可以将 pi 的值指定为类属性,因为它是 circle 上下文中常用的常量。这有助于在整个代码中保持一致性和清晰度。
实例属性由类的特定实例拥有。这意味着对于类的每个对象或实例,实例属性是不同的(除非显式设置为相同的值)。
实例属性通常在 __init__ 方法中定义(有关详细信息,请参见后面),也称为初始值设定项或构造函数,并且它们以 self 为前缀,以表示它们属于类的特定实例。
class Dog: # Class attribute species = "Canis familiaris" def __init__(self, name, age): self.name = name # Instance attribute self.age = age # Instance attribute# Each instance has its own attributesdog1 = Dog("Buddy", 5)dog2 = Dog("Molly", 3)print(dog1.name) # Output: Buddyprint(dog2.name) # Output: Molly属性存储有关对象的数据。类属性由类的所有实例共享。更改 class 属性会影响所有实例。实例属性对于每个实例都是唯一的。更改实例属性仅影响该特定实例。可以使用点表示法(例如,instance.attribute 或 Class.attribute)访问属性。理解属性是 OOP 的基础,因为它们对于定义对象的状态和区分类的不同实例至关重要。它们允许对象在对其进行操作的函数之间保持状态,从而支持将数据封装在对象中。
Python 中的方法是在类中定义的函数,用于定义对象的行为。它们可以对类包含的数据 (属性) 进行操作,并且可以使用类的对象进行访问。方法对于实现对象的功能至关重要。
Python 中有几种类型的方法:
实例方法:对类的实例进行操作,并有权访问实例 (self) 及其属性。类方法:对类本身进行操作,而不是对类的实例进行操作。它们用 @classmethod 装饰器标记,并将 cls 作为第一个参数。静态方法:不对实例或类进行操作。它们用 @staticmethod 装饰器标记,并且不将 self 或 cls 作为第一个参数。它们用于不访问类或实例数据的实用程序函数。为了说明 Python 中方法的使用,让我们创建一个类 Car 来演示实例方法、类方法和静态方法。此示例将有助于阐明如何在类中使用不同类型的方法来操作数据和管理行为。
class Car: # Class attribute total_cars = 0 def __init__(self, make, model, year): self.make = make self.model = model self.year = year Car.total_cars += 1 # Increment the total number of cars each time a new car is created # Instance method def description(self): """Returns a description of the car.""" return f"{self.year} {self.make} {self.model}" # Class method @classmethod def total_cars_created(cls): """Returns the total number of cars created.""" return f"Total cars created: {cls.total_cars}" # Static method @staticmethod def is_vintage(year): """Determines if a car is vintage based on its year.""" return year现在,让我们使用 Car 类创建一些 car 对象,调用实例方法,使用类方法获取创建的汽车总数,并使用 static 方法检查汽车是否被视为老式汽车。
# Creating car objectscar1 = Car("Toyota", "Corolla", 1985)car2 = Car("Ford", "Mustang", 1968)# Using an instance methodprint(car1.description) # Output: 1985 Toyota Corollaprint(car2.description) # Output: 1968 Ford Mustang# Using a class methodprint(Car.total_cars_created) # Output: Total cars created: 2# Using a static methodprint(Car.is_vintage(1985)) # Output: Trueprint(Car.is_vintage(1995)) # Output: False类代码说明实例方法:description 方法是一种实例方法,因为它对 Car 类 (self) 的实例的属性进行操作。它提供描述汽车的格式化字符串。类方法: total_cars_created 方法是一个类方法,如 @classmethod 装饰器所示。它对类本身 (cls) 而不是类的实例进行操作。此方法访问类属性 (total_cars) 以返回创建的 Car 实例的总数。静态方法:is_vintage 方法是一种静态方法,标有 @staticmethod 装饰器。它不将 self 或 cls 作为参数,使其独立于类和实例状态。它执行一项简单的检查,以确定给定年份是否根据老爷车必须来自 1990 年之前的标准将汽车视为老爷车。此示例演示如何在 Python 类中定义和使用实例方法、类方法和静态方法,并展示它们在面向对象的编程方法中组织和管理数据和行为各自的用途和优势。
如果您已经熟悉这三种方法,请随意跳过这部分,但请记住,重复通常有助于强化。
实例方法是 Python 中面向对象编程 (OOP) 的基本概念。它们用于定义可使用类的实例执行的行为和操作。了解实例方法对于在 Python 中设计和实现封装数据和对该数据的操作的类至关重要。
实例方法是在类中定义的函数,用于操作该类的实例。它们可以访问和修改实例的状态,因为它们包含对实例本身的引用,通常名为 self。这个 self 参数是 Python OOP 中的约定,允许实例方法访问同一对象上的属性和其他方法。
要定义实例方法,只需在类中声明一个函数。方法的第一个参数必须是 self,它是对正在调用该方法的实例的引用。这允许该方法访问和操作实例的属性。
下面是一个基本示例,用于说明实例方法的定义和用法:
class Person: def __init__(self, name, age): self.name = name self.age = age # Instance method def introduce_yourself(self): print(f"Hello, my name is {self.name} and I am {self.age} years old.")# Creating an instance of the Person classperson1 = Person("Alice", 30)# Calling an instance method on the person1 instanceperson1.introduce_yourself在此示例中,introduce_yourself 是 Person 类的实例方法。它通过 self 参数访问实例 person1 的 name 和 age 属性,以打印问候语。
在数据科学和工程项目的上下文中,实例方法可用于将与数据处理、分析和可视化相关的功能封装在自定义类中。例如,您可能有一个包装 pandas DataFrame 的 DataFrameWrapper 类,并且该类上的实例方法可能包括清理数据、执行计算或生成特定于数据集的绘图的功能。
理解和利用实例方法允许在数据项目中实现更有组织、可读和可维护的代码,并遵循 OOP 中的封装和抽象原则。
类方法是 Python 面向对象编程 (OOP) 的一个关键功能,它允许您定义对类本身(而不是类的实例)进行操作的函数。这些方法遵循 @classmethod 装饰器,并通过使用 cls 作为其第一个参数来区分,该参数表示类本身,类似于 self 在实例方法中表示类的实例的方式。
类方法只能访问类本身及其属性;他们无权访问实例级数据。这意味着在类方法中,您无法直接访问或修改实例属性。相反,类方法通常用于涉及整个类的操作,而不是单个实例的操作。
定义和使用类方法要定义类方法,请使用方法定义上方的 @classmethod 装饰器。类方法的第一个参数通常命名为 cls,它是对调用该方法的类的引用。这允许类方法访问类变量和其他类方法。
下面是一个演示如何定义和使用类方法的示例:
class Employee: num_of_employees = 0 # Class variable def __init__(self, name, salary): self.name = name self.salary = salary Employee.num_of_employees += 1 @classmethod def get_num_of_employees(cls): return f"Total number of employees: {cls.num_of_employees}"# Accessing a class method without creating an instanceprint(Employee.get_num_of_employees)# Creating instances of Employeeemp1 = Employee("John", 50000)emp2 = Employee("Doe", 60000)# Accessing the class method after creating instancesprint(Employee.get_num_of_employees)在此示例中,get_num_of_employees 是一个返回员工总数的类方法,一个跟踪从 Employee 类创建的实例数的类变量。请注意我们如何在 Employee 类本身上调用 get_num_of_employees,而无需创建该类的实例。
类方法的主要特征对类进行操作:与实例方法不同,类方法与类本身一起使用,而不是与单个实例一起使用。他们可以修改应用于类的所有实例的类状态。使用 cls 参数:类方法中的 cls 参数是指调用该方法的类。这允许类方法访问类变量和其他方法。由 @classmethod Decorator标记:@classmethod 装饰器用于指示方法为类方法。在需要执行与整个类(而不是单个实例)相关的操作的情况下,类方法特别有用。在数据科学项目中,类方法可用于实现从不同格式的数据创建实例的工厂方法,以跟踪与所有实例相关的统计信息,或为数据处理类配置全局设置。
例如,如果您有一个处理数据集的类,则可以使用类方法来设置类级参数,该参数定义该类的所有实例要处理的数据文件(CSV、JSON 等)的默认格式。这种方法促进了干净、有序和模块化的代码库,从而促进了数据项目的更好维护和可扩展性。
要定义静态方法,请使用方法定义上方的 @staticmethod 装饰器。由于静态方法不对类或实例进行操作,因此它们不需要 self 或 cls 参数。它们可以接受任意数量的参数,也可以根本不接受任何参数,具体取决于该方法的设计目的。
下面是一个演示 static 方法的定义和用法的示例:
class MathOperations: @staticmethod def add(x, y): return x + y @staticmethod def multiply(x, y): return x * y# Using static methods without creating an instance of the classprint(MathOperations.add(5, 7)) # Output: 12print(MathOperations.multiply(3, 4)) # Output: 12在此示例中,add 和 multiply 是 MathOperations 类的静态方法,分别执行加法和乘法运算。这些方法是在类本身上调用的,而无需实例化类的对象。
静态方法非常适合执行与类的核心职责没有直接关联的任务的实用程序或帮助程序函数。在数据科学和工程项目中,静态方法可用于计算、数据验证或处理步骤,这些步骤是通用的,与类或其实例的特定状态无关。
例如,如果您有一个处理数据转换的类,则可以包含用于验证数据格式、清理字符串或在度量单位之间进行转换的静态方法。这些方法与类的域相关,但不需要访问类或实例数据,因此它们非常适合静态方法。
使用静态方法有助于保持代码的井井有条、模块化且易于理解,因为它可以清楚地区分属于对象行为的操作和属于通用工具的操作。
Python 中面向对象的编程提供了一种强大而直观的方法来对真实世界的实体进行建模和构建复杂的应用程序。通过了解和使用类、对象和方法,开发人员可以编写更加模块化、可重用且易于理解的代码。
本文标志着一个富有启发性的系列文章的开始,该系列旨在探索面向对象编程 (OOP) 在数据科学、机器学习、深度学习和大型语言模型 (LLMs。
我们探索 Python OOP 的复杂性不仅仅是理解语法或记住模式;这是关于接受一种范式,这种范式可以从根本上改变我们在这些高级领域解决问题的方式。
OOP 提供了一种结构化且可扩展的方式来管理复杂的软件项目,包括数据密集型应用程序。通过将数据和行为封装到对象中,我们可以更自然地对现实世界的现象进行建模,从而使我们的代码更加直观、可维护和可重用。
这在数据科学和机器学习中尤其相关,因为数据和算法的复杂性需要 OOP 唯一有资格提供的组织和抽象水平。
随着我们深入研究本系列,我们将探讨如何应用 OOP 原则来设计健壮的数据模型、实施机器学习算法、管理大型数据集以及构建可扩展的数据管道。我们还将了解 OOP 如何增强 LLMs,从而促进创建更复杂和用户友好的界面,以便与这些强大的模型进行交互。
从类、对象和方法的基本概念到更高级的主题(如继承、多态性和设计模式),本系列旨在为您提供在数据科学和机器学习项目中利用 OOP 的知识和技能。无论您是分析大量数据集、构建预测模型还是开发尖端的 AI 应用程序,了解 OOP 都将为您的工作提供坚实的基础。
请记住,OOP 之旅类似于掌握一种新的思维方式。它是关于通过对象及其交互的镜头来看待编程世界,这种视角可以为复杂问题带来更优雅、更高效的解决方案。
因此,无论您是渴望学习基础知识的初学者,还是希望在数据科学和机器学习的背景下加深对 OOP 的理解的经验丰富的程序员,本系列都有望成为宝贵的资源。加入我们,开始这项激动人心的探索,让我们释放 OOP 在数据科学、ML 等领域的全部潜力。
这只是一个开始,我迫不及待地想分享我从学习笔记和经验中得到的更多见解,因为我们一起继续这段旅程。
来源:自由坦荡的湖泊AI一点号