zoukankan      html  css  js  c++  java
  • Python初识类与对象

    Python初识类与对象

    类与对象

    世界观角度分析类与对象


      类是一个抽象的概念,而对象是一个实体的存在,对象由类创造而出,每个对象之间互相独立互不影响,一个对象可以同时拥有多个类的方法,实例化就是通过某类创建对象的过程。

      比如,某一个人是一个具体的对象,而人类则是人这个对象的来源,人类是一个抽象的概念并且人类又属于哺乳类,所以人也应该具有哺乳类的方法和行为(继承),每个人具有不同的样貌,声音及其自身的不同习惯(多态)。一只猴子不属于人类,因为他没有人类共有的属性和方法,比如:人没有尾巴,人会说话 等等。(封装)。

     

    程序功能角度分析类与对象


      从程序功能角度来看,类是其对象存放共有方法以及属性的地方。并不存在什么抽象不抽象,我一样可以用类来做很多事情。对象确实是由类产生的但是类也是一个对象,因为类它的确可以存放属性以及方法。

      类与对象的关系就在于,类可以存放其实例化对象所需要用到的公共方法与属性,而实例化对象则可以具有类对象不具有的某些属性或方法。

     

    类的定义

     

      定义类发生的几件事:

        1.申请内存空间保存类体代码

        2.将上述内存地址绑定给类名

        3.创建类专属的局部命名空间(注意与函数区分。函数是在执行阶段才会做这件事)

        4.执行类体代码(注意与函数区分。函数的定义阶段不会执行其内部代码)

    img

     

    类的实例化

     

      实例化类发生的几件事情:

        1.调用执行类下的__new__()方法进行类的实例化

        2.调用执行类下的__init__()方法进行实例对象的构造

        3.创建实例对象独有的命名空间

    class People(object):  # <-- 类名:驼峰体, (继承类),可以写也可以不写,推荐写上。
        """这是人类"""  # <-- 说明
    
        number_of_eyes = 2  # 眼睛数量
        number_of_mouths = 1  # 嘴巴数量
        number_of_ears = 2  # 耳朵数量
        number_of_noses = 1  # 鼻子数量
    
        def __init__(self, name, color, height, weight):  # 方法/功能
            self.name = name  # self ---> 实例化对象
            self.color = color
            self.height = height
            self.weight = weight
    
        def speak(self, content):  # 方法/功能
            print("{0}说:{1}".format(self.name, content))
    
    
    # ==== 实例化对象 ====  Ps:可以看到实例化出的对象内存地址完全不同。并且他们还具备了类本身不具备的某些属性,这些属性被称为实例属性
    
    p1 = People("云崖", "黄色", 192, 158)
    print(p1)  # <__main__.People object at 0x00000183AECE3E80>
    print(id(p1))  # 1665085095552
    print(type(p1))  # <class '__main__.People'>
    
    p2 = People("二狗", "黑色", 145, 148)
    print(p2)  # <__main__.People object at 0x00000183AED502B0>
    print(id(p2))  # 1665085538992
    print(type(p2))  # <class '__main__.People'>
    
    # ==== 执行结果 === Ps:可以看到并没有使用()调用类
    
    """
    执行了...
    """

     

    __dict__方法

     

      类:可以查看到当前类下所有的类属性以及类方法

      实例对象:可以查看到当前实例对象下所有的实例属性以及实例绑定方法

     

    class People(object):  # <-- 类名:驼峰体, (继承类),可以写也可以不写,推荐写上。
        """这是人类"""  # <-- 说明
    
        number_of_eyes = 2  # 眼睛数量
        number_of_mouths = 1  # 嘴巴数量
        number_of_ears = 2  # 耳朵数量
        number_of_noses = 1  # 鼻子数量
    
        def __init__(self, name, color, height, weight):  # 方法/功能
            self.name = name  # self ---> 实例化对象
            self.color = color
            self.height = height
            self.weight = weight
    
        def speak(self, content):  # 方法/功能
            print("{0}说:{1}".format(self.name, content))
    
    # ==== 查看类字典 ====
    
    print(People.__dict__)
    
    
    # ==== 查看实例字典 ====
    
    p1 = People("云崖", "黄色", 192, 158)
    print(p1.__dict__)  # {'name': '云崖', 'color': '黄色', 'height': 192, 'weight': 158}
    
    
    # ==== 执行结果 === Ps: 可以看到类字典中具有类所有的属性及方法,而实例字典中只有实例自己的实例属性。(当然你也可以为其添加实例方法)
    
    """
    {'__module__': '__main__', '__doc__': '这是人类', 'number_of_eyes': 2, 'number_of_mouths': 1, 
    'number_of_ears': 2, 'number_of_noses': 1, '__init__': <function People.__init__ at 0x000001B8650DFF70>,
    'speak': <function People.speak at 0x000001B86D4B9700>, '__dict__': <attribute '__dict__' of 'People' objects>,
    '__weakref__': <attribute '__weakref__' of 'People' objects>}
    
    {'name': '云崖', 'color': '黄色', 'height': 192, 'weight': 158}
    """

     

    类属性与实例属性的增删改查

     

      无论是对实例化属性/方法,或者是对类属性/方法进行增删改查,实际上都是非常单纯的对__dict__进行操作。

     

        类属性的增删改查:会影响所有实例化对象。

        实例属性的增删改查:只会影响当前实例化对象,不会影响其他实例化对象以及类。

     

      注意:一般不会对实例新增某个单独的方法,没有这种玩法...而且除开元类编程,类方法的定义也不会放在外部。所以这里只是针对类属性或实例属性的增删改查

     

    class People(object):  # <-- 类名:驼峰体, (继承类),可以写也可以不写,推荐写上。
        """这是人类"""  # <-- 说明
    
        number_of_eyes = 2  # 眼睛数量
        number_of_mouths = 1  # 嘴巴数量
        number_of_ears = 2  # 耳朵数量
        number_of_noses = 1  # 鼻子数量
    
        def __init__(self, name, color, height, weight):  # 方法/功能
            self.name = name  # self ---> 实例化对象
            self.color = color
            self.height = height
            self.weight = weight
    
        def speak(self, content):  # 方法/功能
            print("{0}说:{1}".format(self.name, content))
    
    
    # ==== 实例化对象 ====
    p1 = People("云崖", "黄色", 192, 158)
    p2 = People("二黑", "黑色", 155, 148)
    
    
    # ==== 类属性属性的增 ====
    
    People.number_of_leg = 2  # 腿的数量  相当于 People.__dict__["number_of_leg"] = 2
    
    
    # ==== 类属性、方法的删 ====
    
    del People.number_of_eyes  # 解除属性名number_of_eyes与其堆内存存储值的绑定关系 相当于 del People.__dict__["number_of_eyes"]
    del People.speak  # 解除方法名speak与类方法内存空间的绑定关系 相当于 del People.__dict__["speak"]
    
    # === 类属性的改 ====
    
    People.number_of_mouths = ""  # 相当于 People.__dict__["number_of_mouths"] = "一"
    
    # === 类属性的查 ====
    
    print(People.number_of_leg)  # 2
    print(People.number_of_mouths)  #
    
    
    # === 类的属性增删改查对实例的影响 === 总结:类属性任何增删改查都会影响其实例化对象
    print(p1.number_of_mouths)  #
    print(p2.number_of_mouths)  #
    类属性增删改查对其实例化对象的影响
    class People(object):  # <-- 类名:驼峰体, (继承类),可以写也可以不写,推荐写上。
        """这是人类"""  # <-- 说明
    
        number_of_eyes = 2  # 眼睛数量
        number_of_mouths = 1  # 嘴巴数量
        number_of_ears = 2  # 耳朵数量
        number_of_noses = 1  # 鼻子数量
    
        def __init__(self, name, color, height, weight):  # 方法/功能
            self.name = name  # self ---> 实例化对象
            self.color = color
            self.height = height
            self.weight = weight
    
        def speak(self, content):  # 方法/功能
            print("{0}说:{1}".format(self.name, content))
    
    
    # ==== 实例化对象 ====
    
    p1 = People("云崖", "黄色", 192, 158)
    p2 = People("二黑", "黑色", 155, 148)
    
    
    # ==== 实例化对象属性的增 ====
    
    p1.number_of_leg = 2  # 腿的数量  相当于 p1.__dict__["number_of_leg"] = 2
    
    p1.p1_del_val = "将要删除的值"  # 相当于 p1.__dict__[p1_del_val] = "将要删除的值"
    
    # ==== 实例化对象属性的删 ====
    
    del p1.p1_del_val
    
    # === 实例化对象属性的改 ====
    
    p1.number_of_mouths = ""  # 相当于 p1.__dict__["number_of_mouths"] = "一"
    
    # === 实例化对象属性的查 ====
    
    print(p1.number_of_leg)  # 2
    print(p1.number_of_mouths)  #
    
    # === 实例化对象的属性增删改查对其他实例化对象及类的影响 === 总结:实例化对象对于属性增删改查只影响自己,并不影响其他实例化对象,更不会影响类本身。
    
    # -- 类,与其他实例化对象没有下面两个属性 --
    # print(p2.number_of_leg)
    # print(People.number_of_leg)
    
    print(p1.number_of_mouths)  #
    print(People.number_of_mouths)  # 1
    print(p2.number_of_mouths)  # 1
    
    # Ps: 也可以用  实例对象名称[属性名称]来进行操作。
    实例化对象属性增删改查对其他实例化对象及其类的影响

     

    __init__方法与self参数

     

      __init__方法:是实例化对象时所自动调用的方法。必须返回一个None,否则抛出异常,通常我们用它来构造实例化对象特有的一些属性。

      self参数:在__init__方法中应当是一个即将被实例化的空对象,下面的self.xxx = yyy 其实都是在为这个空对象中的变量名进行赋值操作。而在其他方法中,self参数指的是已经实例化好的对象本身。

     

      前面说过,类是存放实例化对象中一些共有的方法与属性的,这些共用的方法和属性称之为类方法、类属性。那么我们肯定是允许每一个实例化对象拥有自己一些差异化的内容,这些差异化内容的传递其中最简便的方法就是使用Python为我们提供的 __init__ 方法。

     

        def __init__(self, name, color, height, weight):  # 方法/功能
            self.name = name  # self ---> 实例化对象
            self.color = color
            self.height = height
            self.weight = weight

     

    class TestInit(object):
        def __init__(self):
            print(self) # 此时产生一个空对象
            print(self.__dict__)  # {}
            self.x = "任意值"
            print(self.__dict__) 
    
        def testobj(self):
            print(self.__dict__) 
    
    
    t1 = TestInit()  # 这一步实际上是将生产的对象self赋值给了t1
    print(t1)  
    print(t1.__dict__) 
    
    # === self的常规玩法 ===
    
    t1.testobj()  # 我们的实例对象在调用该方法时,会将自身传入进去
    
    # === self的其他玩法 === 当使用类调用某类方法时,我们只需要为其传入一个对象对应上self参数即可。
    
    TestInit.testobj(t1)  # 和上面均属于相同的操作。
    
    t2 = TestInit()
    t2.__dict__ = {"t2专属__dict__": None}
    
    TestInit.testobj(t2)
    
    # ==== 执行结果 ==== 
    
    """
    <__main__.TestInit object at 0x000001A1FF763E80>
    {}
    {'x': '任意值'}
    <__main__.TestInit object at 0x000001A1FF763E80>
    {'x': '任意值'}
    {'x': '任意值'}
    {'x': '任意值'}
    <__main__.TestInit object at 0x000001A1FF7D02B0>
    {}
    {'x': '任意值'}
    {'t2专属__dict__': None}
    """

     

    实例化的绑定方法

     

      当实例化一个类对象的过程中,类方法会变为该实例化对象的绑定方法。绑定方法的作用在于不用传入self参数,而是自动传入self参数为当前的实例化对象。

      Ps:当使用类调用需要传入self的类方法时,必须手动将对象传入self中。注意区分,实例绑定方法与类中的方法。

     

    #
    class People(object):  # <-- 类名:驼峰体, (继承类),可以写也可以不写,推荐写上。
        """这是人类"""  # <-- 说明
    
        number_of_eyes = 2  # 眼睛数量
        number_of_mouths = 1  # 嘴巴数量
        number_of_ears = 2  # 耳朵数量
        number_of_noses = 1  # 鼻子数量
    
        def __init__(self, name, color, height, weight):  # 方法/功能
            self.name = name  # self ---> 实例化对象
            self.color = color
            self.height = height
            self.weight = weight
    
        def speak(self, content):  # 方法/功能
            print("{0}说:{1}".format(self.name, content))
    
    
    # ==== 实例化对象 ====
    
    p1 = People("云崖", "黄色", 192, 158)
    
    # ==== 查看类方法 ====
    
    print(People.speak) # <function People.speak at 0x0000024EE94A8700>
    
    # ==== 查看绑定方法 ==== 
    
    print(p1.speak) # <bound method People.speak of <__main__.People object at 0x000001C6D32B3E80>> bound method 绑定方法

     

    img

     

    类与实例对象的命名空间作用域及属性查找顺序

    img

     

  • 相关阅读:
    《Java数据结构与算法》笔记CH43用栈实现分隔符匹配
    《Java数据结构与算法》笔记CH2无序数组
    《Java数据结构与算法》笔记CH3简单排序
    《Java数据结构与算法》笔记CH41栈的实现
    《Java数据结构与算法》笔记CH42用栈实现字符串反转
    java流程控制.3循环结构
    java方法.1方法的定义和调用
    java流程控制.1scanner
    java方法.2方法的重载
    java方法.3递归
  • 原文地址:https://www.cnblogs.com/Yunya-Cnblogs/p/13046931.html
Copyright © 2011-2022 走看看