当前位置: 首页 > news >正文

【Python】面向对象之类和对象

目录

1面向过程和面向对象

2.类和对象

2.1类

2.2对象

3.定义类

4.类的操作

5.__init()__方法

6.self

6.1self作为实例传参

6.2通过self在类中调用类中的实例属性和实例方法

7.属性

7.1类属性

7.2实例属性

8.方法

8.1实例方法

8.2类方法

8.3静态方法

8.4在类外定义方法

8.5特殊方法

9.动态添加属性与方法

9.1动态给对象添加属性

9.2动态给类添加属性

9.3动态给实例添加方法

9.4动态给类添加方法

9.5动态删除属性与方法

9.6_slots_限制实例属性与实例方法


1面向过程和面向对象

面向过程编程(Procedural Programming)和面向对象编程(OOP)是两种不同的编程范式,它们在软件开发中都有广泛的应用。

Python是一种混合型的语言,既支持面向过程的编程,也支持面向对象的编程。

面向过程的编程是一种以过程为中心的编程方式,主要关注解决问题的步骤,并将这些步骤写成函数或方法。

面向对象的编程是一种以对象为中心的编程方式,主要关注在解决问题的过程中涉及哪些对象以及这些对象如何交互

面向过程举例

想象一下,你要做一顿美味的晚餐。在面向过程编程的思维下,你会把整个做饭的过程拆分成一系列的步骤。

def buy(): print("去超市购买食材。") def wash(): print("清洗蔬菜。") def cut(): print("切菜。") def cook(): print("开始烹饪。") def serve(): print("上菜啦!") buy() wash() cut() cook() serve()

面就是一个典型的面向过程的程序,我们把整个做饭的过程分解成了一个个函数,每个函数完成一个特定的任务,然后按照顺序依次调用这些函数,就可以完成做晚餐的任务啦。这种方式非常直接,适合一些简单的任务,它注重的是程序的流程和步骤。

但是呢,当我们的程序变得越来越复杂,会出现什么问题呢?比如说,我们现在想做不同类型的菜,有些菜可能不需要洗菜,有些菜可能不需要切菜,或者你要同时做几道菜,那我们的代码就会变得越来越长,越来越乱,而且上面的代码步骤是没有通用性的。

面向对象举例(先感受)

用面向对象的思想实现上面的做菜功能

class Dish: def __init__(self, name): self.name = name def prepare(self): pass class Salad(Dish): def prepare(self): print(f"为 {self.name} 购买食材。") print(f"清洗 {self.name} 的蔬菜。") print(f"切 {self.name} 的蔬菜。") class Stew(Dish): def prepare(self): print(f"为 {self.name} 购买食材。") print(f"切 {self.name} 的肉。") print(f"烹饪 {self.name}。") class Soup(Dish): def prepare(self): print(f"为 {self.name} 购买食材。") print(f"煮 {self.name}。") salad = Salad("蔬菜沙拉") stew = Stew("炖肉") soup = Soup("西红柿鸡蛋汤") salad.prepare() stew.prepare() soup.prepare()

在这里,我们创建了一个 Dish 类,它就像是一个菜的模板。然后我们创建了 Salad、Stew 和 Soup 这些子类,它们都继承自 Dish 类。每个子类都有自己的 prepare 方法,这个方法描述了如何准备这道菜。

这样,我们可以看到面向对象编程的优势啦 首先,我们把相关的数据(比如菜的名字)和操作(比如准备菜的过程)都封装在了一个类里面,这叫做 “封装”。而且,不同类型的菜可以有自己独特的准备方法,我们可以根据需要去修改或扩展这些方法,而不会影响其他类。这就像是每个菜都有自己的制作过程。

还有,当我们想要添加新的菜品时,我们只需要创建一个新的子类,定义它自己的 prepare 方法就好,不需要修改原来的代码。

面向对象历史

对象作为编程实体最早是于1960年代由Simula 67语言引入思维。Simula这一语言是奥利-约翰·达尔和克利斯登·奈加特在奥斯陆的挪威计算中心为模拟环境而设计的。(据说,他们是为了模拟船只而设计的这种语言,并且对不同船只间属性的相互影响感兴趣。他们将不同的类型船只归纳为不同的类,而每一个对象,基于它的类,可以定义它自己的属性和行为。)这种办法是分析式程序的最早概念体现。在分析式程序中,我们将真实世界的对象映射到抽象的对象,这叫做“模拟”。Simula不仅引入了“类”的概念,还应用了实例这一思想,这可能是这些概念的最早应用。

2.类和对象

2.1类

类描述了所创建的对象共同的属性(是什么)和方法(能做什么),属性和方法统称为类的成员。

  • 类是对大量对象共性的抽象
  • 类是创建对象的模板
  • 类是客观事物在人脑中的主观反映

2.2对象

  • 在自然界中,只要是客观存在的事物都是对象
  • 类是抽象的,对象是类的实例(Instance),是具体的。
  • 一个对象有自己的状态(属性)、行为(方法)和唯一的标识(本质上指内存中所创建的对象的地址)。

3.定义类

语法

class 类名: """类说明文档""" 类体

类名一般使用大驼峰命名法。

类体中可以包含类属性(也叫类变量)、方法、实例属性(也叫实例变量)等。

​​​​​​​案例

定义一个人的类,包含__init__()方法、eat()方法和drink()方法。

class Person: """人的类""" home = "earth" def __init__(self): self.age = 0 def eat(self): print("eating...") def drink(self): print("drinking...")

4.类的操作

类支持两种操作,成员引用和实例化。

​​​​​​​成员引用

语法

类名.成员名

案例

class Person: """人的类""" home = "earth" def __init__(self): self.age = 0 def eat(self): print("eating...") def drink(self): print("drinking...") home = Person.home # 获取一个字符串 eat_function = Person.eat # 获取一个函数对象 doc = Person.__doc__ # 获取类的说明文档 print(home) # earth print(eat_function) # <function Person.eat at 0x00000232C8230F40> print(doc) # 人的类

​​​​​​​实例化

语法

变量名 = 类名()

案例

class Person: """人的类""" home = "earth" def __init__(self): self.age = 0 def eat(self): print("eating...") def drink(self): print("drinking...") p = Person() # 创建一个对象 print(p.home) # earth print(p.age) # 0 p.eat() # eating... p.drink() # drinking...

5.__init()__方法

__init__() 是一个特殊的方法,也被称作构造函数。__init__() 方法的主要作用是在创建类的对象时,对对象的属性进行初始化。当你使用类名创建一个新的对象时,Python 会自动调用 __init__() 方法,并将新创建的对象作为第一个参数(通常命名为 self)传递给它。

注意:

  • self:这是一个约定俗成的参数名,它代表类的实例对象本身。在方法内部,通过 self 可以访问和修改对象的属性。
  • __init__() 方法不是必需的。如果类中没有定义 __init__() 方法,Python 会使用默认的构造函数,该构造函数不执行任何操作。
  • __init__() 方法只能返回 None,不能返回其他值。如果尝试返回其他值,会引发 TypeError 异常
class Person: """人的类""" home = "earth" def __init__(self, name): self.name = name p = Person("张三") # 创建一个对象 print(p.name) # 张三

6.self

6.1self作为实例传参

self代表类的实例自身。调用实例方法时,实例对象会作为第一个参数被传入。因此,我们调用p.eat()时就相当于调用了Person.eat(p)

class Person: """人的类""" home = "earth" def __init__(self, name): self.name = name def eat(self): print("eating...") def drink(self): print("drinking...") p = Person("张三") # 创建一个对象 p.eat() # eating... Person.eat(p) # eating...

6.2通过self在类中调用类中的实例属性和实例方法

class Person: """人的类""" home = "earth" def __init__(self, name): self.name = name def eat(self): print("eating...") def drink(self): print("drinking...") def eat_and_drink(self): print(self.name) # 在类中调用name self.eat() # 在类中调用eat()方法 self.drink() # 在类中调用drink()方法 p = Person("张三") # 创建一个对象 p.eat_and_drink()

7.属性

7.1类属性

也叫类变量。在类中方法外定义的属性。

​​​​​​​通过类名.属性名实例名.属性名访问

class Person: """人的类""" home = "earth" # 定义类属性 print(Person.home) # 通过类名访问类属性 p1 = Person() # 创建一个实例对象 print(p1.home) # 通过实例名访问类属性,(如果实例没有覆盖这个类属性的值)

​​​​​​​通过类名.属性名添加与修改类属性

class Person: """人的类""" Person.home = "earth" # 添加类属性 print(Person.home) # earth Person.home = "mars" # 修改类属性 print(Person.home) # mars

若使用实例名.属性名则会创建或修改实例属性,因此不建议类属性和实例属性同名。

class Person: """人的类""" home = "earth" p1 = Person() p2 = Person() print(Person.home) # earth print(p1.home) # earth print(p2.home) # earth print("通过 类名.属性名 修改 类属性") Person.home = "mars" print(Person.home) # mars print(p1.home) # mars print(p2.home) # mars print("通过 实例名.属性名 会创建 实例属性") p1.home = "venus" print(Person.home) # mars print(p1.home) # venus print(p2.home) # mars

​​​​​​​所有该类的实例共享同一个类属性

class Person: """人的类""" home = "earth" # 定义类属性,所有实例共享 p1 = Person() # 创建一个实例对象 p2 = Person() # 创建另一个实例对象 print(p1.home) # earth print(p2.home) # earth Person.home = "mars" # 修改类属性 print(p1.home) # mars print(p2.home) # mars

​​​​​​​7.2实例属性

也叫实例变量。在类__init__方法中定义的属性。通过self.属性名定义。

​​​​​​​通过实例名.属性名访问

class Person: """人的类""" def __init__(self, name, age): self.name = name # 定义实例属性 self.age = age # 定义实例属性 p1 = Person("张三", 18) # 创建一个实例对象 print(p1.name, p1.age) # 张三 18 p2 = Person("李四", 81) # 创建一个实例对象 print(p2.name, p2.age) # 李四 81 print(Person.name) # 报错

​​​​​​​通过实例名.属性名添加与修改实例属性

class Person: """人的类""" pass p1 = Person() # 创建一个实例对象 p1.name = "张三" # 添加实例属性 p1.age = 18 # 添加实例属性 print(p1.name, p1.age) # 张三 18 p1.age = 25 # 修改实例属性 print(p1.name, p1.age) # 张三 25

​​​​​​​每个实例独有一份实例属性

class Person: """人的类""" def __init__(self, name): self.name = name # 定义实例属性 self.age = 0 # 定义实例属性 p1 = Person("张三") # 创建一个实例对象 print(p1.name, p1.age) # 张三 0 p1.age = 18 # 修改p1的age属性 print(p1.name, p1.age) # 张三 18 p2 = Person("李四") # 创建另一个实例对象 print(p2.name, p2.age) # 李四 0

8.方法

Python的类中有三种方法:实例方法、静态方法、类方法。

8.1实例方法

  • 实例方法在类中定义,第一个参数为self,代表实例本身。
  • 实例方法只能被实例对象调用。

可以访问实例属性、类属性、类方法。

class Person: """人的类""" home = "earth" def __init__(self, name): self.name = name def instance_method(self): print(self.name, self.home, Person.home) p = Person("张三") p.instance_method() # 张三 earth earth,此时p中没有home实例属性,会去查找home类属性 Person.home = "venus" # 修改类属性 p.home = "mars" # 定义实例属性 p.instance_method() # 张三 mars venus

8.2类方法

  • 类方法在类中通过@classmethod定义,第一个参数为cls,代表类本身。
  • 类方法可以被类和实例对象调用。
  • 可以访问类属性。
  • 在不创建实例的情况下调用,通过类名直接调用,非常方便,适合一些和类整体相关的操作。
class Person: """人的类""" home = "earth" # 定义类属性 @classmethod def class_method(cls): print(cls.home) Person.class_method() # 通过类调用类方法 p1 = Person() # 创建一个实例对象 p1.class_method() # 通过实例对象调用类方法

8.3静态方法

  • 静态方法在类中通过@staticmethod定义
  • 不访问实例属性或类属性,只依赖于传入的参数
  • 可以通过类名或实例调用,但它不会访问类或实例的内部信息,更像是一个工具函数,只是为了方便组织代码,把它放在了类里面。
class Person: """人的类""" home = "earth" # 定义类属性 @staticmethod def static_method(): print("static method") Person.static_method() # 通过类调用静态方法 p1 = Person() # 创建一个实例对象 p1.static_method() # 通过实例对象调用静态方法

8.4在类外定义方法

并非必须在类定义中进行方法定义,也可以将一个函数对象赋值给一个类内局部变量。

# 在类外定义的函数 def f1(self, x, y): print(x & y) class C: f = f1 C().f(6, 13) # 4

8.5特殊方法

方法名中有两个前缀下划线和两个后缀下划线的方法为特殊方法,也叫魔法方法。上文提到的__init__()就是一个特殊方法。这些方法会在进行特定的操作时自动被调用。

几个常见的特殊方法:

​​​​​​​__new__()

对象实例化时第一个调用的方法。

​​​​​​​__init__()

类的初始化方法。

​​​​​​​__del__()

对象的销毁器,定义了当对象被垃圾回收时的行为。使用del xxx时不会主动调用__del__(),除非此时引用计数==0。

​​​​​​​__str__()

定义了对类的实例调用str()时的行为。

​​​​​​​__repr__()

定义对类的实例调用repr()时的行为。str()repr()最主要的差别在于目标用户。repr()的作用是产生机器可读的输出(大部分情况下,其输出可以作为有效的Python代码),而str()则产生人类可读的输出。

​​​​​​​__getattribute__()

属性访问拦截器,定义了属性被访问前的操作。

9.动态添加属性与方法

9.1动态给对象添加属性

class Person: def __init__(self, name=None): self.name = name p = Person("张三") print(p.name) # 张三 p.age = 18 print(p.age) # 18

9.2动态给类添加属性

class Person: def __init__(self, name=None): self.name = name p = Person("张三") print(p.name) # 张三 Person.age = 0 print(p.age) # 0

9.3动态给实例添加方法

​​​​​​​添加普通方法

class Person: def __init__(self, name=None): self.name = name def eat(): print("吃饭") p = Person("张三") p.eat = eat p.eat() # 吃饭

​​​​​​​添加实例方法

给对象添加的实例方法只绑定在当前对象上,不对其他对象生效,而且需要传入 self 参数。需要使用 types.MethodType(方法名,实例对象) 来添加实例方法。

import types class Person: def __init__(self, name=None): self.name = name def eat(self): print(f"{self.name}在吃饭") p = Person("张三") p.eat = types.MethodType(eat, p) p.eat() # 张三在吃饭

9.4动态给类添加方法

给类添加的方法对它的所有对象都生效,添加类方法需要传入 cls 参数,添加静态方法则不需要。

class Person: home = "earth" def __init__(self, name=None): self.name = name # 定义类方法 @classmethod def come_from(cls): print(f"来自{cls.home}") # 定义静态方法 @staticmethod def static_function(): print("static function") Person.come_from = come_from Person.come_from() # 来自earth Person.static_function = static_function Person.static_function() # static function

9.5动态删除属性与方法

  • del对象.属性名
  • delattr(对象,属性名)

9.6_slots_限制实例属性与实例方法

Python允许在定义类的时候,定义一个特殊的__slots__变量,来限制该类的实例能添加的属性。使用__slots__可以限制添加实例属性和实例方法,但类属性、类方法和静态方法还可以添加。__slots__仅对当前类生效,对其子类无效。

import types class Person: __slots__ = ("name", "age", "eat") def __init__(self, name=None): self.name = name def eat(self): print(f"{self.name}在吃饭") def drink(self): print(f"{self.name}在喝水") p = Person("张三") # 添加实例属性 p.age = 10 print(p.age) # 10 # 添加实例方法 p.eat = types.MethodType(eat, p) p.eat() # 张三在吃饭 # 添加实例属性 p.weight = 100 # AttributeError: 'Person' object has no attribute 'weight' # 添加实例方法 p.drink = types.MethodType(drink, p) # AttributeError: 'Person' object has no attribute 'drink'
http://www.jsqmd.com/news/706021/

相关文章:

  • QtScrcpy:重新定义跨设备协同的数字桥梁
  • ai软件开发如何节约烧钱的token202604-插件
  • Voxtral-4B-TTS-2603应用场景:跨境直播实时字幕转语音、短视频多语种配音工具链
  • Kubernetes AI助手:用自然语言提升集群运维效率
  • leetcode hot100 64. 最小路径和 medium 递归优化
  • 2026电缆沟盖板质量解析:电力井盖/草盆井盖/隧道盖板/雨水井盖/高分子复合方形井盖/卡槽式电缆沟盖/双层井盖/选择指南 - 优质品牌商家
  • 2026年4月更新:臭氧发生器企业全景盘点与选型指南 - 2026年企业推荐榜
  • 力扣-18.四数之和
  • 4月27日成都地区热镀锌角钢(安钢、晋南、盛财,型号 L30- L400)现货批发 - 四川盛世钢联营销中心
  • Fairseq-Dense-13B-Janeway创意写作模型助力Proteus仿真项目报告自动化
  • 2026测力传感器技术分享:静态称重传感器/高精度测力传感器/高精度称重传感器/S型测力传感器/动态称重传感器/选择指南 - 优质品牌商家
  • 2026年4月新消息:成都实力酒店装修公司深度解析与选择指南 - 2026年企业推荐榜
  • 国内外主流 RPA 厂商全解析:生态能力、合规治理、落地对比
  • 2026年4月南安优质中学推荐:南安市正观高级中学,多元升学路径的坚实保障 - 2026年企业推荐榜
  • 2026现阶段湖北市场优选工业塔填料供应商:马利冷却塔填料制造商的专业实力解析 - 2026年企业推荐榜
  • Cloudflare Sandbox SDK:在边缘网络安全运行不可信代码的实践指南
  • 2026年现阶段,如何甄选真正有实力的移动居住空间服务商?——以广东微墅科技为例 - 2026年企业推荐榜
  • 相邻节点迭代器
  • ARM平台PPP协议栈移植与优化实战指南
  • 2026现阶段实木地板批发厂家综合实力榜:苏州实木地板智造专家深度解析 - 2026年企业推荐榜
  • 2026年4月吉林地区S波填料优质供应商盘点:良机冷却塔填料智造专家入选 - 2026年企业推荐榜
  • 2026年当下重庆有机鱼深度解析:为何“昇鱼尚水”成为市场焦点? - 2026年企业推荐榜
  • 2026年当前辽宁地区康明冷却塔填料直销工厂甄选要点 - 2026年企业推荐榜
  • CREST分子构象搜索工具完整指南:从零开始掌握高效采样技术
  • 小爱音箱接入大模型实战:open-xiaoai-bridge项目部署与高级配置指南
  • ESP32智能继电器板开发与应用指南
  • 免费SVG编辑器终极指南:Method Draw让你的矢量图形设计变得简单高效
  • 2026优秀办公室装修技术指南:净化厂房装修、办公室设计、办公楼装修、厂房装修及设计、厂房设计、大型写字楼装修选择指南 - 优质品牌商家
  • 4月27日成都地区槽钢(晋南、翅冀、宝得,型号[6.3#-[40#)现货批发 - 四川盛世钢联营销中心
  • 2026养老院智能化技术全解析:养老院软件系统、智慧健康养老、智慧养老服务、智慧养老院系统、最近养老院、养老管理系统选择指南 - 优质品牌商家