Python之路 - 面向对象初识

本章内容

  1. 编程范式介绍
  2. 类与实例
  3. 属性与方法
  4. 构造函数
  5. 命名空间
  6. 属性(静态和动态) 与类的关系
  7. 对象交互与类的组合

一、编程范式

编程是程序员用 特定的语法 + 数据结构 + 算法组成的代码来告诉计算机如何执行任务的过程 , 而实现一个任务的方式有很多种不同的方式 , 对这些不同的编程方式的特点进行归纳总结得出来的编程方式类别,即为编程范式

  • 面向过程编程 Procedural Programming

面向过程编程就是程序从上到下一步步执行 , 基本设计思路就是程序一开始是要着手解决一个大的问题 , 然后把一个大问题分解成很多个小问题或子过程 , 这写子过程再执行的过程再继续分解直到小问题足够简单到可以在一个小步骤范围内解决

在Python中 , 我们通过把大段代码拆成函数 , 通过一层一层的函数调用 , 就可以把复杂任务分解成简单的任务 , 这种分解可以称之为面向过程的程序设计 . 函数就是面向过程的程序设计的基本单元

  • 函数式编程 Functional Programming

函数式编程就是一种抽象程度很高的编程范式 , 纯粹的函数式编程语言编写的函数没有变量 , 函数式编程的一个特点就是 , 允许把函数本身作为参数传入另一个函数 , 还允许返回一个函数 , Python对函数式编程提供部分支持 . 由于Python允许使用变量 , 因此 , Python不是纯函数式编程语言

  • 面向对象编程 Object Oriented Programming

面向对象编程是利用"类"和"对象"来创建各种模型来实现对真实世界的描述 , 使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单 , 并且可以大大提高程序开发效率 , 另外 , 基于面向对象的程序可以使它人更加容易理解你的代码逻辑 , 从而使团队开发变得更从容

二、类与实例

类的语法

class 类名:
    pass

一个栗子??

# 创建一个人的‘类‘,首字母要大写
class Person(object):
# 构造函数,初始化属性
   def __init__(self,name):
       self.name = name
   # 人可以吃饭
   def eat(self):
       print("I am eatting")
# 创造了一个叫做‘Lyon‘的人
p = Person(‘Lyon‘)
# 执行吃饭功能
p.eat()
# 执行结果: I am eatting
  • 类 (class)

类就是 对现实生活中一类具有共同特征事物的抽象

类起到一个模板的作用 , 当我们创建一个类时 , 就相当于创建了一个初始的‘模型‘ , 我们可以通过这个‘模型‘ 来创建出一个个具有相同特征或功能的事物 , 来帮助我们更好的处理问题

在上述栗子中类名Person 后有一个(object) , 这是新式类的写法 , 而在python3.x 以上的版本中 , 默认为新式类 , 所以也可直接 class Person:

我们创建类时 , 都默认继承了object类 , object详解见后期文章

  • 实例 (instance)

我们知道类是一个抽象 , 既然是抽象那就是不可操作的 , 所以我们如果进行操作 , 就需要将这一抽象的概念变成具体的事物 , 这个过程我们称为实例化

实例化: 由抽象的类转换成实际存在的对象的过程

实例: 由类进行实例化所得到的对象 , 上述栗子中的 p 就是一个实例

三、属性与方法

属性是实体的描述性质或特征 , 比如人有名字 , 年龄 , 性别等 . 当然还有人所能做的事情也是一种属性 , 比如吃饭 , 睡觉 , 喝水等 . 对于这两种属性 , 一种是表示特征的 , 叫做静态属性 , 另一种则是表示功能的 , 叫做动态属性

在Python中 , 我们将静态属性 就称为属性 , 将动态属性 就称为方法 , 并且以变量来表示属性 , 以函数表示方法 , 见下图:

PS:类中的函数已经不叫函数了 , 而叫做方法

属性包括 : 实例变量 , 类变量

调用方式: 类名 . 属性名

class Person:
   # 类变量
   role = ‘student‘
   # 构造函数
   def __init__(self,name):
       # 实例变量
       self.name = name

方法包括 : 普通方法 , 属性方法 , 类方法 , 静态方法

调用方式: 类名 . 方法名( )

class Person:
# 普通方法
   def eat(self):
       pass

特殊的类属性


属性名


说明


__dict__


查看类或对象成员 , 返回一个字典


__name__


查看类的名字


__doc__


查看类的描述信息 , 即注释部分


__base__


查看第一个父类


__bases__


查看所有父类 , 返回一个元组


__module__


查看类当前所在模块


__class__


查看对象通过什么类实例化而来

PS:对于属性和方法 , 在网上分类各种各样的都有 , 比如字段 , 还有菜鸟教程中的一些 , 其实本质上都是一个东西

四、构造函数

在上述例子中 , 可以看到有一个__init__ 方法 , 这个方法叫做构造方法 , 用于初始化属性 , 所以如果我们要设置属性 , 那么构造方法是必须要的

self

我们直接通过实例来说明

class Foo:
   def __init__(self,name):
       self.name = name
   def func(self):
       print(id(self))
a = Foo(‘Lyon‘)
# 打印实例a的内存地址
print(id(a))
# 调用类中的func方法,即打印self的内存地址
a.func()
‘‘‘
执行结果:
1703689404544
1703689404544
结果分析: 我们发现a的内存地址和self的内存地址是一样的,也就是说self其实就是实例本身 那么在我们进行实例化的时候,self.name = name 就是给实例添加一个name属性,该属性的值就是我们在实例化时传入的‘Lyon‘ 所以如果我们需要给对象添加属性的话,可以直接通过 对象.属性名 = 属性值 的方式进行添加
‘‘‘

将上栗子中的构造函数再换个姿势看看

a = Foo(‘Lyon‘)
# 等价于如下,用类名调用类中的方法
Foo.__init__(a,‘Lyon‘)
# Python解释器会帮我们自动触发__init__方法,所以再如下
Foo(a,‘Lyon‘)

五、命名空间

在函数中 , Python解释器在执行时 , 会将函数名称依次加载到命名空间 , 类当然也一样

我们创建一个类时 , Python解释器一执行就会创建一个类的命名空间 , 用来存储类中定义的所有名称( 属性和方法 ) , 而我们进行实例化时 , Python解释器又会为我们创建一个实例命名空间 , 用来存放实例中的名称

当我们利用 类名. 名称 来访问对象属性 ( 静态与动态 ) 时 , Python解释器会先到该对象的命名空间中去找该名称 , 找不到就再到类 ( 该对象实例化之前的类 ) 的命名空间中去找 , 最后如果都没找到 , 那么就抛出异常了

访问属性实例

class A(object):
   """   这是一个类   """
   pass a = A()
# 访问实例a的__doc__属性
print(a.__doc__)
#执行结果: 这是一个类

解释说明: 对于实例a本身是肯定没有__doc__ 属性的 , 这毋庸置疑 , 因为我们根本就没有使用构造函数来增加实例属性 . 根据执行结果显示 , 我们是访问到了这个类中的__doc__ 属性 , 那么你会说这个类也没看见 __doc__ 属性啊 , 其实类A是有的 , 因为它继承了object类 , 至于object类是什么 , 它里面有什么 ? 看后续文章吧

六、属性(静态和动态)与类的关系

由于Python是动态语言 , 所以Python的赋值机制都是通过动态绑定来实现的

  • 类属性共享给所有对象

先实例后说明

class Foo:
   # 定义一个类变量,特意用的容器类型来说明
   name = [‘Lyon‘]
# 实例化
a = Foo()
b = Foo()
# 访问a,b中的name属性
print(‘实例a中的name属性:‘, a.name)
print(‘实例b中的name属性:‘, b.name)
# 查看a,b,Foo中name属性的内存地址
print(id(a.name))
print(id(b.name))
print(id(Foo.name))
print(‘------------------‘)
# 修改类变量
Foo.name = ‘a‘
# 再次访问a,b中的name属性
print(‘实例a中的name属性:‘, a.name)
print(‘实例b中的name属性:‘, b.name)
# 修改a中的name属性? 不,是新增
a.name = [‘Lyon‘]
# 再次查看a,b中name属性的内存地址
print(id(a.name))
print(id(b.name))
‘‘‘
执行结果:
实例a中的name属性: [‘Lyon‘]
实例b中的name属性: [‘Lyon‘]
2247471754696
2247471754696
2247471754696
------------------
实例a中的name属性: a
实例b中的name属性: a
2247471792392
2247471754696
‘‘‘

说明:

  1. 特意使用容器类型来进行实验 , 因为在Python中容器类型内存地址一样只有一个原因 , 那就是两者作用的是同一个对象
  2. 我们第一步查看内存地址时 , a, b, Foo三者中的name属性的内存地址是一样的 , 实例可以通过 实例.类变量名 的方式进行访问 , 并且所有实例都共享类属性name
  3. a.name = [‘Lyon‘] 这一步其实并不是修改a中的name属性 , 要知道name属性是类的并不是实例的 , 执行这一步会为实例a加上一个新的同名name属性 , 由于赋值绑定会将原来访问类属性name的通道破坏掉 , 但是并不会影响b对类属性name的访问
  • 类中的方法是绑定到所有对象的

先实例后说明

class Foo:
   def func(self):
       pass
a = Foo()
b = Foo()
# 打印a,b中func的内存地址
print(a.func)
print(b.func)
# id返回的是10进制表示的内存地址,转换成16进制
print(hex(id(a)))
print(hex(id(b)))
‘‘‘
执行结果:
<bound method Foo.func of <__main__.Foo object at 0x000001A7D2F74080>>
<bound method Foo.func of <__main__.Foo object at 0x000001A7D3759898>> 0x1a7d2f74080
0x1a7d3759898
‘‘‘

说明:

  1. 方法名与内存地址存在一个映射关系 , 通过执行结果我们可以发现 , a.func所在的内存地址与a的内存地址是一样的 , 则说明func绑定到了a中
  2. a.func 与b.func 的内存地址是不一样的 , 因为每一个实例都开辟了自己内存空间 , func绑定进去的位置自然不一样
  • 实例本身的属性是实例独有的

我们通过类创建一个实例 , 就会在内存中新开辟一块内存空间来存放这个实例的所有属性 , 实例属性一旦创建 , 基本跟类就没有什么太大的关系了 . 如果要修改实例属性那么就只能通过实例来进行修改了 , 并且实例与实例之间也是互不干扰的

如下图中 , 类与实例 , 实例与实例 都开辟了自己的内存空间

七、对象交互与类的组合

对象交互

class Person:
   def __init__(self, name):
       self.name = name
   def attack(self,per):
       print("{} attacked {}".format(self.name, per.name))
lyon = Person("Lyon")
kenneth = Person("kenneth")
lyon.attack(kenneth)
# 执行结果: Lyon attacked kenneth

类的组合

传参时组合

class BirthDate:
   def __init__(self, year, month, day):
       self.year = year
       self.month = month
       self.day = day
class Person:
   def __init__(self, name, birthdate):
       self.name = name
       self.birthdate = birthdate
p = Person(‘Lyon‘, BirthDate(2000, 1, 1))

定义时组合

class BirthDate:
   def __init__(self, year, month, day):
       self.year = year
       self.month = month
       self.day = day class Person:
   def __init__(self, name, year, month, day):
       self.name = name
       self.birthdate = BirthDate(year, month, day)
 p = Person(‘Lyon‘, 2000, 1, 1)
时间: 2024-10-13 23:27:21

Python之路 - 面向对象初识的相关文章

python基础之面向对象初识

一 面向对象初识 Python要么是面向过程要么是面向对象. 概念及优缺点: 面向过程的程序设计的核心是过程,过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了程序的复杂度 缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身. 应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等. 面向对象的

python之路---16 初识面向对象

三十五.初识面向对象 一 .面向对象和面向过程比较 ①面向过程:一切以事物的发展流程为核心    优点:负责的问题流程化,编写相对简单 缺点:可扩展性差 ②面向对象:一切以对象为中心. 一切皆为对象. 具体的某一个事务就是对象 优点:可扩展性强 缺点:编程的复杂度高于面向过程 二.类和对象 ①类:就是图纸,创建对象的第一步     对象:通过类造出来的具体事物, ②基本格式 class  类名:            #创建类    类名用驼峰格式 def __init__(self,参数): 

python之路 面向对象(一)

面向过程vs面向对象 面向过程的核心是过程,是解决问题的步骤. 优点:极大降低了写程序的复杂度,只需顺着要执行的步骤,码代码即可. 缺点:一套程序解决一个问题,牵一发动全身. 面向对象的核心是对象. 优点:解决了程序的扩展性,对某一个单一对象的修改,会映射到整个体系中. 缺点:可控性差,无法向面向过程一样可以很精准的预测到结果,面向对象程序一旦开始就由对象之间的交互解决问题,无法预测结果. 类和对象(实例) python中一切皆对象,类型的本质就是类,包括字典,列表,数字,字符串等. 在pyth

python之路——面向对象(基础篇)

面向对象编程:类,对象 面向对象编程是一种编程方式,此编程方式的落地需要使用 "类" 和 "对象" 来实现,所以,面向对象编程其实就是对 "类" 和 "对象" 的使用. 面向对象技术简介 类(class):用来描述有相同属性和方法的对象的集合,它定义了集合中每个对象所共有的属性和方法. 对象(object):类的实例 创建类和对象 1 class Person: 2 3 def __init__(self,name,age):

python之路---面向对象编程(二)

类的继承 1.在python3中,只有新式类,新式类的继承方式为:广度优先.而python2中,经典类的继承方式为:深度优先.那么我们来看看深度优先和广度优先的区别吧 如下图,为类之间的继承关系.B,C继承A,D继承B,E继承C,F继承D,E   深度优先: class A: # def foo(self): # print 'from A' pass class B(A): # def foo(self): # print 'from B' pass class C(A): # def foo

python之路---面向对象编程(一)

一.设计思想的发展 面向机器(代码复杂,效率低,学习成本高,开发周期长)-------->面向过程(扩展性差,不适用多变的需求改变)----------->面向对象(扩展性好,但是可控性差) 二.面向过程和面向对象对比 面向过程: 定义:面向过程的核心是过程(即流水线式设计),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了程序的复杂度 缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也

Python之路-面向对象&amp;继承和多态&amp;类属性和实例属性&amp;类方法和静态方法

一.面向对象 编程方式 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强-" 什么是面向对象 面向对象就不像面向过程那样按照功能划分模块了,它所关注的是软件系统有哪些参与者,把这些参与者称为对象,找出这些软件系统的参与者也就是对象之后,分析这些对象有哪些特征.哪些行为,以及对象之间的关系,所以说面向对象的开发核心是对象 什么是类 面向对象编程的两个重要的概念:类和对象 类是

Python 基础之面向对象初识与类的封装

一: 面向对象类的初识#(1) 类的定义#三种方式:#1.class MyClass:    pass #2.推荐class MyClass():    pass #3.class MyClass(object):    pass#(2) 类的实例化class MyClass():    pass#类的实例化,实例化对象obj = MyClass() #obj 就是一个对象#(3)类的基本结构只有成员方法和成员属性对象.属性  对象.方法()#例:class MyClass():    #成员属

Python之路-面向对象

一.面向对象 1.面向对象和面向过程比较 面向过程关注问题解决的步骤,是一种机械式的思维方式,流水线方式实现. 面向对象中对象是特征和技能的结合体,面向对象是对现实世界的模拟,好比 上帝创造世界. 面向过程优点可以将复杂问题流程化,简单化,面向对象的优点是可扩展性强. 2. 类和对象 类和对象的关系:类是一系列对象相似特征与技能的结合体. 现实世界:现有具体的对象--------------->总结相似之处------------>形成类 程序中:先定义类-------------->调