python学习之路(五)------类和面向对象

一、类和对象

1.1 什么是对象?

   名人曾经说过,世间万物皆为对象,人十个对象,动物植物甚至是一张椅子,也是一个对象。可以从世间万物总结出来,对象是由属性和方法构成的。一个对象的特征称为属性,如人的皮肤,眼睛,嘴巴等等,用来描述一个对象具体表现;二一个对象的行为则称为方法,如人会编程,狗会吃屎等。那么将这些对象在代码中就可以描述为

# 人这个对象

# 对象的属性 name = 'faker' age = 22 hobby = ['lol', 'ball'] # 对象的方法 def playgame(game): print("play %s" % (game))

可以看出,对象把原本分散的数据和功能都整合到了一起,这样可以解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。这样提高了程序的可拓展性。

1.2 类和对象

类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体

 

 

  • 在现实世界中,我们是先有了对象,才会产生类,因为只有我们真正看见了一个具体的对象,才能总结出它的属性和方法。
  • 在编程世界中,先定义类,才会产生对象。

 

1.3 创建类

  • 在python中调用class方法创建一个类
# 人这个对象
class human:
    # 对象的属性
    name = 'faker'
    age = 22
    hobby = ['lol', 'ball']

    # 对象的方法
    def playgame(self, game):
        print("play %s" % (game))

 

  • 这些代码在定义中便会执行,因此便会产生了新的名称空间,我们可以通过__dict__的方法来查看
# 人这个对象
class human:
    name = 'faker'
    age = 22
    hobby = ['lol', 'ball']

    def playgame(self, game):
        print("play %s" % (game))

print(human.__dict__)

"""
{'__module__': '__main__', 'name': 'faker', 'age': 22, 'hobby': ['lol', 'ball'], 'playgame': <function human.playgame at 0x02E50DB0>, '__dict__': <attribute '__dict__' of 'human' objects>, '__weakref__': <attribute '__weakref__' of 'human' objects>, '__doc__': None}
"""

 

  • 可以看到,类所有的属性都存放在这个属性字典中.我们可以通过.的方法调用这些属性方法,实际上就是在操作属性字典。
# 人这个对象
class human:
    name = 'faker'
    age = 22
    hobby = ['lol', 'ball']

    def playgame(self, game):
        print("play %s" % (game))


print(human.name)  # 等同于human.__dict__['name']
human.age = 30  # human.__dict__['age'] = 30
print(human.age)
print(human.hobby)
human.playgame('h1','lol') # 这里传入h1是因为human中playgame方法中的self就是一个实例对象本身,所以在类条用这个方法是需要传入一个实例,否则会报错TypeError: playgame() missing 1 required positional argument: 'game'

“””
faker
30
['lol', 'ball']
play lol
“””

 

 

二、面向对象编程

  面向对象程序设计(Object Oriented Programming)作为一种新方法,其本质是以建立模型体现出来的抽象思维过程和面向对象的方法。模型是用来反映现实世界中事物特征的。任何一个模型都不可能反映客观事物的一切具体特征,只能对事物特征和变化规律的一种抽象,且在它所涉及的范围内更普遍、更集中、更深刻地描述客体的特征。通过建立模型而达到的抽象是人们对客体认识的深化。

2.1 类的实例化

调用类的过程称为类的实例化,拿到的返回值就是一个对象或实例

# 人这个对象
class human:
    name = 'faker'
    age = 22
    hobby = ['lol', 'ball']

    def playgame(self, game):
        print("play %s" % (game))

h1 = human()
print(h1)

"""
<__main__.human object at 0x02D0F050>
"""

 

拿到了这个实例,我们就可以通过点的方式调用它们的类的属性内容

# 人这个对象
class human:
    name = 'faker'
    age = 22
    hobby = ['lol', 'ball']

    def playgame(self, game):
        print("play %s" % (game))

h1 = human()
print(h1.name)
print(h1.age)
print(h1.hobby)
h1.playgame('lol')

"""
faker
22
['lol', 'ball']
play lol
"""

 

 

2.2 __init__方法--------为实例创造独立空间

  • 在没有运用__init__方法是,我们调用实例的__dict__方法,可以发现是一个空字典,证明实例是只有类的公共属性,而没有自己的独特属性,这显然是不符合实际的。
print(h1.__dict__)

“””
{}
“””

 

  • 调用__init__方法,专门对实例初始化自己独立的特征,这个方法在对象创建之后便会执行。
class human:
    species = 'animal'

    def __init__(self, name, age, hobby):
        self.name = name
        self.age = age
        self.hobby = hobby
        print(‘self ’,self)

    def playgame(self, game):
        print("play %s" % (game))


h1 = human('faker', 22, ['lol', 'ball'])  # 这里为什么__init__方法有四个参数,而实例化时只传递了三个参数?因为self是实例对象本身,h1就是传递给了self
print(h1.__dict__)

“””
self <__main__.human object at 0x02D4FB50>
{'name': 'faker', 'age': 22, 'hobby': ['lol', 'ball']}
“””

 

  •  同样的实例也是通过.方法来操作属性,实例可以操作类的属性
h1 = human('faker', 22, ['lol', 'ball'])
print(h1.name)
h1.hobby[1] = 'sing'  # 等同于h1.__dict__['hobby'][1] = 'sing'
print(h1.hobby)
h1.playgame('lol')

“””
faker
['lol', 'sing']
play lol
“””

 

 

2.3 类属性和实例属性

  • 类的属性具体可以分为数据属性和函数属性,通过调用__dict__方法可以查看,通过.方法可以调用属性(实际上就是操作属性字典)。
  • 实例的属性就是通过__init__方法实例化出来的特有的属性,实例属性没有函数属性,只能调用类的函数属性。
class human:
    species = 'animal'

    def __init__(self, name, age, hobby):
        self.name = name
        self.age = age
        self.hobby = hobby

    def playgame(self, game):
        print("play %s" % (game))


h1 = human('faker', 22, ['lol', 'ball'])
h2 = human('uzi', 21, ['lol', 'bath'])
print('h1.__dict__', h1.__dict__)
print('h2.__dict__', h2.__dict__)
print('human.__dict__', human.__dict__)


“””
h1.__dict__ {'name': 'faker', 'age': 22, 'hobby': ['lol', 'ball']}
h2.__dict__ {'name': 'uzi', 'age': 21, 'hobby': ['lol', 'bath']}
human.__dict__ {'__module__': '__main__', 'species': 'animal', '__init__': <function human.__init__ at 0x03030DB0>, 'playgame': <function human.playgame at 0x07591CD8>, '__dict__': <attribute '__dict__' of 'human' objects>, '__weakref__': <attribute '__weakref__' of 'human' objects>, '__doc__': None}
“””

 

用个图更好地表示

 

 

 

  

 

2.4 类属性和实例属性的绑定

  • 在类中定义的变量(__init__之外)的变量是类的数据属性,也是实例公共的数据属性,指向同一个内存地址。

  

print(id(human.species))
print(id(h1.species))
print(id(h2.species))

"""
46823520
46823520
46823520
"""

 

  • 而类中定义的函数属性,是绑定给对象的,不同的对象就是不同的绑定方法,所以类的函属性内存地址不同和对象的调用的函数的内存地址不同。
  • 具体而言,就是类实例化了哪个实例,就将函数属性绑定给哪个实例。实例调用函数就是将自己作为参数传给self,即   h1.playgame('lol') = human.playgame('h1','lol') 
print(human.playgame)
print(h1.playgame)
print(h2.playgame)


"""
<function human.playgame at 0x077FFCD8>
<bound method human.playgame of <__main__.human object at 0x078033F0>>
<bound method human.playgame of <__main__.human object at 0x07803410>>
"""

 

  

 

2.5 属性查找顺序和修改规则

  • 我们实例化的对象的名称空间里只存放对象特有的属性,公共属性存放于的属性字典中。对象在访问一个属性时,会先从自己的属性字典中去查找,若没找到,再会去类的属性字典中去查找。
class human:
    species = 'animal'
    name = 'human'

    def __init__(self, name, age, hobby):
        self.name = name
        self.age = age
        self.hobby = hobby

    def playgame(self, game):
        print("play %s" % (game))


h1 = human('faker', 22, ['lol', 'ball'])
print(h1.name)
print(h1.species)

"""
faker # 对象自己的属性字典就存在name属性,所以name为faker
animal # 对象属性字典中没有species属性,所以去类的属性字典查找
"""

 

  • 类可以修改公共属性,而对象不能修改 
class human:
    species = 'animal'
    name = 'human'

    def __init__(self, name, age, hobby):
        self.name = name
        self.age = age
        self.hobby = hobby

    def playgame(self, game):
        print("play %s" % (game))


h1 = human('faker', 22, ['lol', 'ball'])
human.species = 'people'
print('the first', h1.species)
print('the first', h1.__dict__)
h1.species = 'advanced _animal'
print('the second', h1.species)
print('the second', h1.__dict__)


"""
the first people
the first {'name': 'faker', 'age': 22, 'hobby': ['lol', 'ball']}
the second advanced _animal
the second {'name': 'faker', 'age': 22, 'hobby': ['lol', 'ball'], 'species': 'advanced _animal'}
"""

可以看到,用类去修改公共属性时,属性会被修改;而用对象去修改时,会在对象的属性字典里新增一个属性。

 

 

 
posted @ 2019-11-19 14:17  想吃手抓饼  阅读(149)  评论(0编辑  收藏  举报