lesson 040 —— 面向对象简介

关于面向对象的简单介绍。

三大编程范式

  1. 面向过程编程
  2. 函数式编程
  3. 面向对象编程

面向对象概念

  • 类: 把一类事物相同的特征和动作整合到一起就是类。类是一个抽象的概念。类是一种数据结构。
  • 对象:就是基于类而创建的一个具体的事物(具体存在的),也是特征和动作整合到一起;对象就是类的实例化,具体化。对象是一个具体的事物。
  • 类与对象的关系: 对象是由类产生的,对象是类的实例化,具体化。
  • 实例化: 由类产生对象的过程叫实例化,类实例化的结果就是一个对象,或者叫一个实例(实例=对象)。
1. 声明类
class 类名:"""类的文档字符串"""类体# 声明一个类,类名一般首字母大写,使用驼峰命名法
# 代表的是:class Data(object):
class Data:"""这是一个时间的类。"""pass# 实例化这个类
d1 = Data()

在 Python3 中使用新式类,所有的类都继承自一个父类:object。

2. 属性

类是用来描述一类事物的,类的对象指的是一类事物中的一个个体。事物的属性分为:

  1. 数据属性: 就是变量
  2. 函数(方法)属性: 就是函数,在面向对象里称为方法。

注意:类和对象都使用点 . 来访问自己的属性。

3. 类的属性
  1. 类的数据属性: 类的数据属性是所有对象共享的

  2. 类的方法属性: 类的函数属性是绑定给对象用的

  3. 一些内置的类的特殊属性

    类名.__name__# 类的名字(字符串)
    类名.__doc__# 类的文档(字符串)
    类名.__base__# 类的第一个父类(在讲继承时会讲)
    类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
    类名.__dict__# 类的字典属性
    类名.__module__# 类定义所在的模块
    类名.__class__# 实例对应的类(仅新式类中)

    使用 dir(类名) 可以查看类的属性!!!

class Data:"""关于时间的类"""# 类的数据属性year = 2018month = 7day = 35week = '星期三'# 类的方法属性def print_year():print('2018 年')# 需要传入参数和这个类绑定,不传也没问题,可是不会绑定# 可是要使用参数的时候,就需要传入 selfdef print_data(self):print('%4d 年 %2d 月 %2d 日' % (self.year, self.month, self.day))if __name__ == '__main__':d1 = Data()d2 = Data()print("类的属性")print("Data.year: %d" % Data.year)print("Data.print_year: ")Data.print_year()# 这里类调用的话,就需要传入一个参数print("Data.print_data: ")Data.print_data(Data)print()print("类的属性是所有对象公有的")print("id Data.year: %d" % id(Data.year))print("id d1.year: %d" % id(d1.year))print("id d2.year: %d" % id(d2.year))print()print("函数属性是对于不同对象的")print("addr Data.print_data: ", Data.print_data)print("addr d1.print_data: ", d1.print_data)print("addr d2.print_data: ", d2.print_data)print("id Data.print_data: %d" % id(Data.print_data))print("id d1.print_data: %d" % id(d1.print_data))print("id d2.print_data: %d" % id(d2.print_data))print()print("d1 对象与类属性关系")print("d1.year: %d" % d1.year)# 这里不能调用,因为类里面是没有参数的,对象调用的话就会传入对象,即 self 参数#print("d1.print_year: ")#d1.print_year()print("d1.print_data: ")d1.print_data()print()print("类改变数据属性:")print("Data.year: %d" % Data.year)print("d1.year: %d" % d1.year)print("d2.year: %d" % d2.year)print("执行 Data.year = Data.year + 1")Data.year = Data.year + 1print("Data.year: %d" % Data.year)print("d1.year: %d" % d1.year)print("d2.year: %d" % d2.year)print()print("对象改变数据属性:")print("Data.year: %d" % Data.year)print("d1.year: %d" % d1.year)print("d2.year: %d" % d2.year)print("执行 d1.year = d1.year + 1")d1.year = d1.year + 1print("Data.year: %d" % Data.year)print("d1.year: %d" % d1.year)print("d2.year: %d" % d2.year)print("执行 d2.year = d2.year + 1")d2.year = d2.year + 1print("Data.year: %d" % Data.year)print("d1.year: %d" % d1.year)print("d2.year: %d" % d2.year)print()print("改变之后的地址")print("id Data.year: %d" % id(Data.year))print("id d1.year: %d" % id(d1.year))print("id d2.year: %d" % id(d2.year))print()

结果:

类的属性
Data.year: 2018
Data.print_year:
2018 年
Data.print_data:
2018 年  7 月 35 日类的属性是所有对象公有的
id Data.year: 139849464558928
id d1.year: 139849464558928
id d2.year: 139849464558928函数属性是对于不同对象的
addr Data.print_data:  <function Data.print_data at 0x7f313da13d90>
addr d1.print_data:  <bound method Data.print_data of <__main__.Data object at 0x7f313da440f0>>
addr d2.print_data:  <bound method Data.print_data of <__main__.Data object at 0x7f313da44128>>
id Data.print_data: 139849464102288
id d1.print_data: 139849465338376
id d2.print_data: 139849465338376d1 对象与类属性关系
d1.year: 2018
d1.print_data:
2018 年  7 月 35 日类改变数据属性:
Data.year: 2018
d1.year: 2018
d2.year: 2018
执行 Data.year = Data.year + 1
Data.year: 2019
d1.year: 2019
d2.year: 2019对象改变数据属性:
Data.year: 2019
d1.year: 2019
d2.year: 2019
执行 d1.year = d1.year + 1
Data.year: 2019
d1.year: 2020
d2.year: 2019
执行 d2.year = d2.year + 1
Data.year: 2019
d1.year: 2020
d2.year: 2020改变之后的地址
id Data.year: 139849465104656
id d1.year: 139849464558832
id d2.year: 139849464558896

从以上实例中我们可以验证得到这几个结论:

  1. 类的数据属性是所有对象共享的,我们称为类的数据

    id Data.year: 139849464558928
    id d1.year: 139849464558928
    id d2.year: 139849464558928
  2. 当使用改变类的数据之后,我们发现,所有的对象数据都改变了,即他们的地址都是一样的。

    类改变数据属性:
    Data.year: 2018
    d1.year: 2018
    d2.year: 2018
    执行 Data.year = Data.year + 1
    Data.year: 2019
    d1.year: 2019
    d2.year: 2019
  3. 但是,我们使用对象改变类的属性之后,仅仅是这个对象的数据变了,而其它对象和类的都不会改变。我们可以得知:Python 中,直接改变对象中类的数据,其实是创建了新的对象数据,而不是改变了类的数据,即将指向类的数据的变量指向了一个新的数据地址!!!

    对象改变数据属性:
    Data.year: 2019
    d1.year: 2019
    d2.year: 2019
    执行 d1.year = d1.year + 1
    Data.year: 2019
    d1.year: 2020
    d2.year: 2019
    执行 d2.year = d2.year + 1
    Data.year: 2019
    d1.year: 2020
    d2.year: 2020id Data.year: 139849465104656
    id d1.year: 139849464558832
    id d2.year: 139849464558896

    注意:Python 中几乎所有变量的赋值,都是将新的数据地址赋值给这个变量,即这个变量指向了一个新的内存地址,而不是改变变量指向的对应内存地址的数据!!!

  4. obj.name 会先从 obj 自己的名称空间里找 name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常.

  5. 类中的函数属性需要一个 self 形参来和这个类的对象绑定。在 Python 中,self 代表的就是对象,定义的函数属性本质上是定义一个函数。(虽然不加 self 程序不会报错,但是不会和对象绑定)。虽然绑定了,但是当类调用的时候可以随便传入参数,只要传入的参数使函数可以运行。

    def print_data(self):print('%4d 年 %2d 月 %2d 日' % (self.year, self.month, self.day))Data.print_data(Data)
  6. 类的函数属性没有 self 参数的时候,只有类可以调用,对象是无法调用的,它是类的方法

    # 这里不能调用,因为类里面是没有参数的,对象调用的话就会传入对象,即 self 参数
    #print("d1.print_year: ")
    #d1.print_year()
  7. 通过类来创建对象的时候,对于绑定的类的函数,即有 self 形参的函数,实际上是将那个函数复制到了对象的空间中,有了自己的内存,与类中的地址不一样。所以,通过类创建对象,虽然是同一个类,同一个类的函数,但是,每个对象都会复制函数,每个对象有他们自己的存储这个函数的内存,即变成了对象自己的函数,而不是类的函数。虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法!!!

    addr Data.print_data:  <function Data.print_data at 0x7f313da13d90>
    addr d1.print_data:  <bound method Data.print_data of <__main__.Data object at 0x7f313da440f0>>
    addr d2.print_data:  <bound method Data.print_data of <__main__.Data object at 0x7f313da44128>>
    id Data.print_data: 139849464102288
    id d1.print_data: 139849465338376
    id d2.print_data: 139849465338376
  8. 强调:绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,就会将本身当做第一个参数传给方法,即自动传值(方法 __init__ 也是一样的道理)

    注意:绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数 selfself 可以是任意名字,但是约定俗成地写出self。

    # 类调用
    Data.print_data(Data)# 对象调用
    d1.print_data()
4. 对象

对象是类的实例化,类实例化的一个结果称为一个实例或者一个对象。

class Student:school='xxoo'def __init__(self, name, sex, age):print('开始创建')self.name = nameself.age = ageself.sex = sexprint('创建结束')def learn(self):print('%s is learning' % self.name) #新增self.namedef eat(self):print('%s is eating' % self.name)def sleep(self):print('%s is sleeping' % self.name)# 创建对象
s1=Student('李坦克','男',18)
s2=Student('王大炮','女',38)
s3=Student('牛榴弹','男',78)

对象不仅有函数属性,还有类的数据属性,另外,还有它自己的数据属性。它们都可以通过 . 来访问

对象的 __dict__ 属性只有函数属性,说明了对象只有数据属性

要使用 __init__ 来设置初始化一个对象的方法,它没有返回值。

对于每一个类里定义的参数,都必须要有 self 形参,且必须要有,还要放在第一个位置。

5. 类属性增删改查

类属性的操作使用 .del 进行操作,当使用类进行类属性的更改,它的所有的实例对象,不管是改变之前创建的,或者是改变之后创建的,都会跟着改变;当使用对象对类属性重新赋值之后,类属性实际不会改变,而这个对象的类属性转变为对象属性。数据属性与函数属性都一样,同样的方式。

注意: 要调用类的属性,只能通过类名加点或者对象加点的方式调用,如果直接使用变量名,则调用的是全局的变量。调用不到类的属性。

country = '中国'
class N:country = '日本'num = ['a', 'b',]def __init__(self):print(country)   # 输出的是中国n1 = N()
print(N.num)
print(n1.num)
n1.num.append(1)   # 没有给类属性赋新值,只是改变了类属性,所以结果是类属性改变了
print(N.num)
print(n1.num)

结果:

中国
['a', 'b']
['a', 'b']
['a', 'b', 1]
['a', 'b', 1]

转载于:https://www.cnblogs.com/arelive/p/python-40.html

lesson 040 —— 面向对象简介相关推荐

  1. Java面向对象(一)面向对象简介和初步 了解

    一.面向对象简介 面向对象是相对面向过程而言的. 面向过程注重的是过程,强调的是动作: 面向对象注重的是对象,只要找到了对应的对象,那么就自然拥有了对象所具有的一切功能 面向对象是基于面向过程的 面向 ...

  2. 阿里云【名师课堂】Java面向对象开发2:面向对象简介

    阿里云[名师课堂]Java面向对象开发2:面向对象简介 编程语言发展阶段 编程语言发展阶段 面向机器语言:汇编语言 面向过程语言:C语言.FORTRAN等 面向对象语言:Java等 面向过程的核心是编 ...

  3. golang 面向对象 简介

    go中,我们的面向对象使用的就是struct,但时代不同了,这次我们的struct也可以有"成员函数"了. 定义一个典型的面向对象方式 package main import &q ...

  4. API 类和面向对象简介

    2019独角兽企业重金招聘Python工程师标准>>> API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数, 目的是提 ...

  5. C#OOP之一面向对象简介

    今天我们开始第一次课,我们本门课的题目叫"C#面向对象程序设计语言".那么什么是"C#",什么又是"面向对象"呢?,程序设计语言的概念,我们 ...

  6. 侯杰(面向对象上01)面向对象简介

    注释:本章需要重点掌握的是面向对象的定义以及基于对象的定义 &曾经学过某种语言 @变量(variables) @类型(types):int, float, char, struct..... ...

  7. 【达内课程】面向对象简介

    文章目录 概念了解 举例说明:创建一个Soldier类 举例说明:创建一个FlashLight类 举例说明:创建一个Car类 类中包含的变量 类中的方法 概念了解 Java是一种面向对象的程序设计语言 ...

  8. python面向对象简介_python(23)- 面向对象简单介绍

    面向概述 面向过程:根据业务逻辑从上到下写垒代码 面向过程的设计的核心是过程,过程即解决问题的步骤, 面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西 优点:极大降低了程序的复杂 ...

  9. ES6对象(2):面向对象与类

    目录 一.面向对象简介 二.类(构造函数的语法糖) 1.传统的构造函数的问题 2.类的特点 三.类的其他书写方式 1.可计算的成员名 2.getter和setter 3.静态成员 4.字段初始化器 5 ...

  10. javascript基础学习一--面向对象

    面向对象简介 面向过程就是亲力亲为,事无巨细,步步紧跟,不能跳过(做饭过程) 面向对象:找一个对象,指挥得结果.(叫外卖,不关注怎么做饭,求结果) 函数也是对象,指函数封装性.(用来不告诉你核心怎么实 ...

最新文章

  1. pandas使用iteritems函数迭代地查看dataframe中的每个数据列(iterate over each column of a dataframe)
  2. LeetCode--014--最长公共前缀(java)
  3. [译]Node v5.0.0 (Stable)
  4. js进阶正则表达式方括号(方括号作用)(js正则是在双正斜杠之中:/[a-z]/g)...
  5. 指定的服务已经标记为删除_你的电话号码被标记过吗?你知道这件事情还能赚钱吗?...
  6. 操作系统上机作业--使用系统调用实现mycp
  7. python3 一些常用的数学函数
  8. 轻量级Java持久化框架,Hibernate完美助手,Minidao 1.6.2版本发布
  9. c++多线程结束后需要释放_缓刑结束后是否需要继续坐牢?
  10. 让IE8按照IE7的模式解释网页-【一句话】
  11. 修复ext4日志(jbd2)bug( Ext4 文件系统有以下 Bug)
  12. cli vue 卸载_记录使用@vue/cli搭建Vue3项目完整流程
  13. linux jar 运行 停止,[转] Linux中启动和停止jar包的运行
  14. IntelliJ IDEA 面板、菜单介绍
  15. 25-[jQuery]-ajax
  16. ZK在ZUL页面使用HTML
  17. 京东联盟API-二合一链接转链接口-线报转链-京粉转链接口
  18. 百度地图,坐标反查,拾取坐标位置
  19. 学习java哪个网课最好_学习Java的最佳方法
  20. 王道考研操作系统复习笔记

热门文章

  1. 用Map集合来统计一个字符串数组中每个字符串的个数
  2. MyBatis的常见面试题
  3. xpath定位相邻元素方法
  4. python数据类型二(列表和元组)
  5. element-UI快速上手例子运行失败
  6. DockOne微信分享( 一零二):基于容器的日志管理实践
  7. 清除Mac OS X文件系统的附加属性@
  8. Arcgis Javascript API 开发笔记
  9. Cannot delete or update a parent row: a foreign key constraint fails
  10. Why can't Gmail forward outgoing mail?