• 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'}
    """

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

     
  • 相关阅读:
    用户体验
    dwz中权限控制与跳转(转)
    synchronized详解
    CodeIgniter笔记
    linux,apache,php,mysql常用的查看版本信息的方法
    dwz中展开左侧菜单的指定列表
    Apache与Nginx的优缺点比较(转)
    如何在Oracle中复制表结构和表数据 【转载】
    apache配置虚拟主机
    Disallowed Key Characters(转)
  • 原文地址:https://www.cnblogs.com/liangweijiang/p/11885703.html
Copyright © 2020-2023  润新知