python基础(23):面向过程与面向对象的优劣、初识面向对象

1. 面向过程与面向对象的优劣

面向过程的程序设计的核心是过程(流水线式思惟),过程即解决问题的步骤,面向过程的设计就比如精心设计好一条流水线,考虑周全何时处理什么东西。python

优势是:极大的下降了写程序的复杂度,只须要顺着要执行的步骤,堆叠代码便可。git

缺点是:一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身。编程

应用场景:一旦完成基本不多改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。数据结构

面向对象的程序设计的核心是对象(上帝式思惟),要理解对象为什么物,必须把本身当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也能够创造出来。面向对象的程序设计比如如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题须要四我的:唐僧,沙和尚,猪八戒,孙悟空,每一个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的属性和方法),然而这并很差玩,因而如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。而后取经开始,师徒四人与妖魔鬼怪神仙互相缠斗着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取。函数

面向对象的程序设计的spa

优势是:解决了程序的扩展性。对某一个对象单独修改,会马上反映到整个体系中,如对游戏中一我的物参数的特征和技能修改都很容易。设计

缺点:可控性差,没法向面向过程的程序设计流水线式的能够很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题即使是上帝也没法预测最终结果。因而咱们常常看到一个游戏人某一参数的修改极有可能致使阴霸的技能出现,一刀砍死3我的,这个游戏就失去平衡。code

应用场景:需求常常变化的软件,通常需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方。对象

在python 中面向对象的程序设计并非所有。blog

面向对象编程可使程序的维护和扩展变得更简单,而且能够大大提升程序开发效率 ,另外,基于面向对象的程序可使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。

了解一些名词:类、对象、实例、实例化

类:具备相同特征的一类事物(人、狗、老虎)

对象/实例:具体的某一个事物(隔壁阿花、楼下旺财)

实例化:类——>对象的过程(这在生活中表现的不明显,咱们在后面再慢慢解释)

2. 初识面向对象

python中一切皆为对象,类型的本质就是类,因此,无论你信不信,你已经使用了很长时间的类了。

>>> dict #类型dict就是类dict
<class 'dict'>
>>> d=dict(name='eva') #实例化
>>> d.pop('name') #向d发一条消息,执行d的方法pop
'eva'

从上面的例子来看,字典就是一类数据结构,我一说字典你就知道是那个用{}表示,里面由k-v键值对的东西,它还具备一些增删改查的方法。可是我一说字典你能知道字典里具体存了哪些内容么?不能,因此咱们说对于一个类来讲,它具备相同的特征属性和方法。

而具体的{'name':'eva'}这个字典,它是一个字典,可使用字典的全部方法,而且里面有了具体的值,它就是字典的一个对象。对象就是已经实实在在存在的某一个具体的个体。

再举一个其余的例子,通俗一点,好比你如今有一个动物园,你想描述这个动物园,那么动物园里的每一种动物就是一个类,老虎、天鹅、鳄鱼、熊。他们都有相同的属性,好比身高体重出生时间和品种,还有各类动做,好比鳄鱼会游泳,天鹅会飞,老虎会跑,熊会吃。

可是这些老虎熊啥的都不是具体的某一只,而是一类动物。虽然他们都有身高体重,可是你却没有办法肯定这个值是多少。若是这个时候给你一只具体的老虎,而你还没死,那你就能给他量量身高称称体重,这些数值是否是就变成具体的了?那么具体的这一只老虎就是一个具体的实例,也是一个对象。不止这一只,其实每一只具体的老虎都有本身的身高体重,那么每一只老虎都是老虎类的一个对象。

在python中,用变量表示特征,用函数表示技能,于是具备相同特征和技能的一类事物就是‘类’,对象是则是这一类事物中具体的一个。

3. 类

3.1 初识类

格式:

class 类名:
    类体

咱们建立一个类:

class Person:   #定义一我的类
  role = 'person'  #人的角色属性都是人
  def walk(self):  #人均可以走路,也就是有一个走路方法,也叫动态属性
    print("person is walking...")

3.2 类的做用

3.2.1 属性引用(类名.属性)

class Person:   #定义一我的类
  role = 'person'  #人的角色属性都是人
  def walk(self):  #人均可以走路,也就是有一个走路方法
    print("person is walking...")

print(Person.role)  #查看人的role属性
print(Person.walk)  #引用人的走路方法,注意,这里不是在调用

3.2.2 实例化

类名加括号就是实例化,会自动触发__init__函数的运行,能够用它来为每一个实例定制本身的特征。

class Person:   #定义一我的类
  role = 'person'  #人的角色属性都是人
  def __init__(self,name):
    self.name = name  # 每个角色都有本身的昵称;
        
  def walk(self):  #人均可以走路,也就是有一个走路方法
    print("person is walking...")

print(Person.role)  #查看人的role属性
print(Person.walk)  #引用人的走路方法,注意,这里不是在调用

实例化的过程就是类——>对象的过程

本来咱们只有一个Person类,在这个过程当中,产生了一个对象,有本身具体的名字、攻击力和生命值。

语法:

对象名 = 类名(参数)

p = Person('egon')  #类名()就等于在执行Person.__init__()
#执行完__init__()就会返回一个对象。这个对象相似一个字典,存着属于这我的自己的一些属性和方法。

3.2.3 查看属性和调用方法

print(egg.name)     #查看属性直接 对象名.属性名
print(egg.walk())   #调用方法,对象名.方法名()

3.2.4 self

self:在实例化时自动将对象/实例自己传给__init__的第一个参数,你也能够给他起个别的名字,可是正常人都不会这么作。由于修改后其余人就不认识了。

3.2.5 类属性的补充

一:咱们定义的类的属性到底存到哪里了?有两种方式查看

dir(类名):查出的是一个名字列表
类名.__dict__:查出的是一个字典,key为属性名,value为属性值

二:特殊的类属性

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

4. 对象

4.1 初识对象

人除了走路以外,还应该具有吃的功能。

class Person:  # 定义一我的类
  role = 'person'  # 人的角色属性都是人

  def __init__(self, name, age, gender):
    self.name = name  # 每个角色都有本身的昵称;
    self.age = age  # 每个角色都有本身的攻击力;
    self. gender= gender  # 每个角色都有本身的生命值;

  def eat(self,food):  
    # 人能够吃食物,这里的食物也是一个对象。
    # 人吃食物,那么食物的数量会随着人吃的次数而降低
    food.num -= self.num

对象是关于类而实际存在的一个例子,即实例

对象只有一种做用:属性调用

p = Person('egon',20,'男')
print(p.name)
print(p.age)
print(p.gender)

固然了,你也能够引用一个方法,由于方法也是一个属性,只不过是一个相似函数的属性,咱们也管它叫动态属性。
引用动态属性并非执行这个方法,要想调用方法和调用函数是同样的,都须要在后面加上括号。

print(p.eat)

我知道在类里说,你可能还有好多地方不能理解。那咱们就用函数来解释一下这个类呀,对象呀究竟是个啥,你偷偷的用这个理解就行了,不要告诉别人,毕竟一万我的眼里就有一万个哈姆雷特。

def Person(*args,**kwargs):
  self = {}
  def attack(self,dog):
    dog['life_value'] -= self['aggressivity']

  def __init__(name,aggressivity,life_value):
    self['name'] = name
    self['aggressivity'] = aggressivity
    self['life_value'] = life_value
    self['attack'] = attack

  __init__(*args,**kwargs)
  return self

egg = Person('egon',78,10)
print(egg['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   #查看对象的属性,直接用 对象名.属性名 便可
对象名.方法名()     #调用类中的方法,直接用 对象名.方法名() 便可

4.2 对象之间的交互

如今咱们已经有一我的类了,经过给人类一些具体的属性咱们就能够拿到一个实实在在的人。
如今咱们要再建立一个狗类,狗就不能打人了,只能咬人,因此咱们给狗一个bite方法。
有了狗类,咱们还要实例化一只实实在在的狗出来。
而后人和狗就能够打架了。如今咱们就来让他们打一架吧!

4.2.1 建立一个狗类和人类

class Dog:  # 定义一个狗类
  role = 'dog'  # 狗的角色属性都是狗

  def __init__(self, name, breed, aggressivity, life_value):
    self.name = name  # 每一只狗都有本身的昵称;
    self.breed = breed  # 每一只狗都有本身的品种;
    self.aggressivity = aggressivity  # 每一只狗都有本身的攻击力;
    self.life_value = life_value  # 每一只狗都有本身的生命值;

  def bite(self,people):
    # 狗能够咬人,这里的狗也是一个对象。
    # 狗咬人,那么人的生命值就会根据狗的攻击力而降低
    dog.life_value -= self.aggressivit
class Person:  # 定义一我的类
  role = 'person'  # 人的角色属性都是人

  def __init__(self, name, aggressivity, life_value):
    self.name = name  # 每个角色都有本身的昵称;
    self.aggressivity = aggressivity  # 每个角色都有本身的攻击力;
    self.life_value = life_value  # 每个角色都有本身的生命值;

  def attack(self,dog):  
    # 人能够攻击狗,这里的狗也是一个对象。
    # 人攻击狗,那么狗的生命值就会根据人的攻击力而降低
    dog.life_value -= self.aggressivity

4.2.2 实例化一只狗和人

wc = Dog('旺财','中华田园犬',10,1000)  #创造了一只实实在在的狗wc
xhh = Person('小灰灰',20,10000) #创造了一个实实在在的人xhh

4.2.3 交互egon打wc一下

print(wc.life_value)         #看看wc的生命值
xhh.attack(wc)               #xhh打了wc一下
print(wc.life_value)         #wc掉了20点血

4.3 类命名空间与对象、实例的命名空间

建立一个类就会建立一个类的名称空间,用来存储类中定义的全部名字,这些名字称为类的属性

而类有两种属性:静态属性和动态属性

  • 静态属性就是直接在类中定义的变量

  • 动态属性就是定义在类中的方法

4.3.1 其中类的数据属性是共享给全部对象的

>>>id(egg.role)
4341594072
>>>id(Person.role)
4341594072

4.3.2 而类的动态属性是绑定到全部对象的

>>>egg.attack
<bound method Person.attack of <__main__.Person object at 0x101285860>>
>>>Person.attack
<function Person.attack at 0x10127abf8> 

建立一个对象/实例就会建立一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性

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

相关文章
相关标签/搜索