python基础之面向对象编程

面向对象编程思想

  • 面向对象是一门编程思想,编程思想仅仅是一门思想,与任何技术无关
  • 核心是对象两字,对象可以理解为特征与技能的结合体
  • 基于该编程思想编写程序,就好比创造世界,一种造物主的思维方式
  • 优点:可扩张性强
  • 缺点:编写程序的复杂难度比面向过程高

以上都是纯理论,理解下用自己的话能编出来就行,下面来说说核心对象

在现实世界中,通过一个个的对象,根据相同的特征和行为,再分门别类。

但是在程序中,必须先有类,再通过调用类,创建对象

那么,咱们如何定义类,又如何创建对象呢?(暂时还是先说理论吧,不然看代码,估计直接懵逼了……)



关于类的致命三问:什么是类?有什么用?怎么使用?

  • 类的定义:就是类型、类别,跟现实的分类类似。是一系列对象之间相同特征和行为(技能)的结合体
  • 类的作用:个人理解,就是为了创建对象用的。

(终于要写代码了,哈哈哈哈哈哈哈)

  • 类的语法
class 类名:
    特征  # 在python 中,用变量来表示特征
    行为  # 在python 中,用函数来表示行为,也就是大家所说的技能

现在,我们来写一个人类,人类的特征有名字,年龄,性别,行为有吃饭,跑步,玩,撸代码了!

"""
人类
    特征:名字、年龄、性别
    行为:吃饭、跑、玩
"""
class Person:
    # 这些都是人的特征
    name = "dawn"  # 姓名
    age = 27  # 年龄
    sex = "男"  # 性别

    # 这些都是人的行为(技能)
    def eat(self):
        # 吃饭
        print("民以食为天o(∩_∩)o 哈哈")

    def run(self):
        # 跑步
        print("英雄救美,不存在的!别怂!赶紧跑!!!")

    def play(self):
        # 玩
        print("大爷!欢迎下次来玩儿啊!")

print(Person)
print(Person.name)
print(Person.play)

输出结果

<class ‘__main__.Person‘>       # Person 的打印结果
dawn            # Person.name 的打印结果
<function Person.play at 0x0000022E54FA7DC8>  # Person.play 的打印结果

瞅了这么久,发现了吗?类名,类的行为,类的属性都是咋用的?(理论又来了~~~)

  • 类名的命名规范:使用驼峰命名法,即单词的首字母得大写!
  • 类提供了一种便捷的获取名字的方式,就是类名.名字。类的名字包含特征和行为。咱们将类的特征称之为属性,类的行为称之为方法
  • 在类的内部定义函数(也就是行为的时候,默认有一个参数self),这个是干啥的,等会说

通过输出的内容来看,类名指向的是类的内存地址。如何来查看类的名称空间呢?看代码……

print(Person.__dict__)

输出结果

{‘__module__‘: ‘__main__‘, ‘name‘: ‘dawn‘, ‘age‘: 27, ‘sex‘: ‘男‘, ‘eat‘: <function Person.eat at 0x00000228C1683558>, ‘run‘: <function Person.run at 0x00000228C1683B88>, ‘play‘: <function Person.play at 0x00000228C1687DC8>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘Person‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘Person‘ objects>, ‘__doc__‘: None}

惊不惊喜!意不意外!对,这就是Person类的名称空间中的内容!!!也就是说类的名称空间是在定义阶段产生

到这里,咱们就该聊聊类是如何使用的了。前面咱就说了,类的调用就是对象的创建。说的类的使用就得知道对象是啥了!耐心点,好玩的还在后面!



哈哈哈哈哈!我三连问回来啦!——什么是对象?有什么用?怎么使用?

  • 对象的定义特征与技能的结合体
  • 语法类名()

咱们来瞅瞅对象是如何创建的,类又是如何调用的 !

# 上面咱定义了一个Person类,这里直接拿来用
# 调用Person类后会产生一个对象,使用一个变量接收
p1 = Person()

# 输出p1 的属性
print(p1.name, p1.age, p1.sex)

# 使用p1 的方法
p1.play()
p1.run()
p1.eat()

输出结果

dawn 27 男   # p1的属性
大爷!欢迎下次来玩儿啊!    # p1.play()的结果
英雄救美,不存在的!别怂!赶紧跑!!!  # p1.run()的结果
民以食为天o(∩_∩)o 哈哈   # p1.eat()的结果

刚刚获取了对象的属性(也就是查询),发现没有,这些属性都是类的,我们能否对对象的属性做个增删改呢?如果修改了对象的属性,类是否随之改变呢?动手试试

修改对象的属性,其实就是对象自己增加了属性

# 修改属性
print(Person.__dict__)  # 修改前,Person的名称空间
print(p1.__dict__)      # 修改前,p1的名称空间
p1.name = "haha"        # 修改对象的name 属性,实际上是p1对象自己新增了name 属性
print(Person.__dict__)   # 修改后,Person的名称空间
print(p1.__dict__)      # 修改后,p1的名称空间

输出结果

增加对象的属性

# 增加属性
print(p1.__dict__)
print(Person.__dict__)
p1.hobby = "read"
print(p1.__dict__)
print(Person.__dict__)

输出结果

删除对象的属性

# 删除属性
del p1.sex
print(p1.sex)
print(Person.__dict__)

输出结果

纵观以上的结果,咱说了那些属性都在类的名称空间里,那么有没有什么方法,让这些属性是通过对象来增删改查的呢?

当然有的啦!那就是__init__() !我们来看看使用方式

# 定义一个类
class Person:
    # 这些都是人的特征
    name = "dawn"  # 姓名

    # __init__()
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    # 这些都是人的行为(技能)
    def eat(self):
        # 吃饭
        print("民以食为天o(∩_∩)o 哈哈")

# 通过类创建两个对象,分别是p1和p2
p1 = Person("haha", 39, "男")
p2 = Person("lee", 21, "女")

# 查看Person类的名称空间
print(Person.__dict__)
# 查看对象p1的名称空间
print(p1.__dict__)
# 查看对象p2的名称空间
print(p2.__dict__)

输出结果

发现什么了没有?

__init__()实现了对象的个性化定制,而且创建对象在传参时,没有传self这个参数。

那是因为__init__()在调用时,会将对象本身作为第一个参数传入。原因后期学习以后,才知道。现在就做一个总结好了

  • 由对象来调用类的内部函数,称为对象的绑定方法。对象的绑定方法特殊之处在于:会将对象本身当作第一个参数传入方法(咱可以回头看看定义类的时候,是不是每个行为也就是方法,都有self参数)
  • __init__() 在调用类时触发,会做以下事情:
    • 将对象本身当作第一个参数传入方法(原因:对象的绑定方法)
    • 调用时,传入的其他参数一并被 __init__() 接收

接着,我们来看看,对象是如何对属性做增删改查的

# 获取p1的属性
print(f"姓名:{p1.name},性别:{p1.sex},年龄:{p1.age}")

# 修改p1的属性
print(f"修改前,p1的名称空间:{p1.__dict__}")
p1.age = 27
print(f"修改后,p1的属性值:{p1.age}")
print(f"修改后,p1的名称空间:{p1.__dict__}")

输出结果

再来看看增加(前面就已经举例了,算了还是再举一个吧)和删除

# 获取p1的属性
print(f"姓名:{p1.name},性别:{p1.sex},年龄:{p1.age}")

# 增加属性
print(f"增加hobby前:{p1.__dict__}")
p1.hobby = "read"
print(f"hobby的取值:{p1.hobby}")
print(f"增加hobby后:{p1.__dict__}")

# 删除属性
print(f"删除sex前:{p1.__dict__}")
del p1.sex
print(f"删除sex后:{p1.__dict__}")

输入结果

还有个地方,就是咱刚才一直在说名称空间,那么类的名称空间和对象的名称空间,有什么关系呢?

咱们继续看代码

# 通过类创建一个对象
p1 = Person("haha", 39, "男")

# 查看Person类的名称空间和属性
print(f"Person的名称空间:{Person.__dict__}")
print(f"Person的name属性值:{Person.name}")
# 查看对象p1的名称空间和属性
print(f"p1的名称空间:{p1.__dict__}")
print(f"p1的name属性值:{p1.name}")

# 删除p1的属性name,再打印p1的名称空间和属性
del p1.name
print(f"删除name属性后,p1的名称空间:{p1.__dict__}")
print(f"删除name属性后,p1的name属性值:{p1.name}")

输出结果

看到没?对象的属性删除后,再去调用这个属性,并没有报错,而是将类中的同名属性值获取了过来

那如果类中没有这个属性呢?我们再来看看

class Person:
    # 这些都是人的特征
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

# 通过类创建一个对象
p1 = Person("haha", 39, "男")
# 查看对象p1的名称空间和属性
print(f"p1的名称空间:{p1.__dict__}")
print(f"p1的name属性值:{p1.name}")
# 删除p1的属性name,再打印p1的名称空间和属性
del p1.name
print(f"删除name属性后,p1的名称空间:{p1.__dict__}")
print(f"删除name属性后,p1的name属性值:{p1.name}")

输出结果

报错了!!!由此我们可以总结下:

对象先从自身名称空间查找,没有就去类的名称空间查找,再没有就会报错。

对象名字的查找顺序:

对象自身 ----→  ----→ 都没有,报错



定义类及调用的固定模式

class 类名:
    def __init__(self,参数1,参数2):
        self.对象的属性1 = 参数1
        self.对象的属性2 = 参数2

    def 方法名(self):pass

    def 方法名2(self):pass

对象名 = 类名(1,2)  #对象就是实例,代表一个具体的东西
                  #类名() : 类名+括号就是实例化一个类,相当于调用了__init__方法
                  #括号里传参数,参数不需要传self,其他与init中的形参一一对应
                  #结果返回一个对象
对象名.对象的属性1   #查看对象的属性,直接用 对象名.属性名 即可
对象名.方法名()     #调用类中的方法,直接用 对象名.方法名() 即可

原文地址:https://www.cnblogs.com/7758520lzy/p/12120196.html

时间: 2024-11-10 15:57:20

python基础之面向对象编程的相关文章

Day6 - Python基础6 面向对象编程

Python之路,Day6 - 面向对象学习 本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 引子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢? 你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色 1 2 3 4 5 6 7 8 9 10 11

Python基础6-1 面向对象编程

概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强..." 面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处. while True:     if cpu利用率 > 90%:         #发送邮件提醒         连接邮箱服务器         发送邮件     

Python基础day-16[面向对象编程(未完)]

面向对象: 相对于面向过程编程来讲,面向对象的扩展性比较强.但是同时带来的问题是可控性差,面向对象编程不像面向过程那样可以很精准的预测结果.面向对象程序一旦开始就由对象之间进行交互解决问题. 面向对象程序设计只是用来解决程序扩展性的. 什么是对象: 举一个例子:每个人都有自己特征和技能,那么每个人就是一个对象.对象就是特征与技能的结合体. 什么是类: 每个人都有自己独有特征也有和别人同样的技能或者特征.例如:基本每个人都会吃饭,都会睡觉,都会说话或者某两个人眼睛都挺大.我们可以把这些共同的技能或

Python基础-第六天-面向对象编程

本篇内容 1.面向对象编程介绍 2.类的定义及各部分的介绍 3.属性 4.方法 5.面向对象的特性-封装 6.面向对象的特性-继承 7.面向对象的特性-多态 8.新式类和经典类 一.面向对象编程介绍 1.编程的原则 无论用什么编程范式来编程都要记住的原则是,避免写重复代码,代码要易扩展.一定要遵循可读性好.易扩展的原则. 2.面向对象编程(Object-Oriented Programming)介绍 OOP编程的主要作用是使代码修改和扩展变的更容易: 面向对象编程是利用类和对象来帮助我们实现功能

python基础之面向对象编程介绍、类和对象

面向对象变成介绍 面向过程编程 核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西.主要应用在一旦完成很少修改的地方,如linux内核.git.apache服务器等 优点:极大的降低了程序的设计复杂度 缺点:可扩展性差,改动一个地方很可能要改多个地方,牵一发而动全身 面向对象编程:不是编程的全部,只是用来解决软件可扩展性的 核心是对象(上帝式思维),对象作为程序的基本单元,一个对象包含了数据和操作数据的函数.面向对象就是把计算

Python基础6 面向对象编程

本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 引子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢? 你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def per

Python基础6-2 面向对象编程

本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 类的成员 类的成员可以分为三大类:字段.方法和属性 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段.而其他的成员,则都是保存在类中,即:无论对象的多少,在内存中只创建一份. 一.字段 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, 普通字段属于对象 静态字段属于类 class Province:     # 静态字段     c

Python基础-week06 面向对象编程进阶

一.反射 1.定义:指的是通过字符串来操作类或者对象的属性 2.为什么用反射? 减少冗余代码,提升代码质量. 3.如何用反射? class People: country='China' def __init__(self,name): self.name=name obj=People('jame') #hasattr #print('country' in People.__dict__) print(hasattr(People,'country')) #getattr #print(Pe

python基础之socket编程

python基础之socket编程   一 TCP/IP五层模型 在每一层都工作着不同的设备,比如我们常用的交换机就工作在数据链路层的,一般的路由器是工作在网络层的. 在每一层实现的协议也各不同,即每一层的服务也不同.下图列出了每层主要的协议. 各层功能 注明:ARP和RAPR两个到底属于哪一层呢? 由于IP协议使用了ARP协议,所以经常把ARP协议划到网络层,但是ARP协议是为了从网络层使用的IP地址解析出在数据链路层使用的MAC地址,所以有些地方也把ARP协议划分到数据链路层,但是一般情况下