第九章 类和对象

一、 基本概念
1. 对象 
    --- 有具体行为和属性的东西
2. 类
    --- 将需求的对象划分为不同的类,具有相同属性或者行为的对象划分为一个类
3. 类和对象之间的关系
    --- 类是模板,对象是根据类创建的实例
        类是对象的抽象,对象是类的具体实现
    > 开发从对象开始分析 -- 将对象分类 - 考虑每个类都有什么样的属性和行为
    
二、 定义和初始化
1. 类的定义
    class 类名[(default = object)]:
        '注释'
        类体
        
    对象名 = 类() # 括号中是否有参数,取决于init方法
    
    eg.
    class Person:
        pass
    p1 = Person()
    #打印对象
    perint(p1)
    #查看对象对应类注释
    print(p1.__doc__)
    
2. 类的属性和行为
    属性: 变量绑定的形式
    行为: 函数定义的形式
2.1 动态创建
    (1) 动态定义属性
        ① 创建对象
        ② 对象.属性名 = 属性值
        
        p1.name = '张珊'
        p1.age = 23
        print()
    
    (2) 动态定义行为
        ① 创建对象
        ② 创建方法
        ③ 对象.方法()
        
        eg.
        def run (self):
            print('我在跑步')
        p1.run = run
        p1.run(p1)
        p2 = Person()
    
    > 动态创建属性和行为的局限性:
        —— 每一个对象都要赋予属性和方法
        —— 动态增加的属性与方法仅对当前对象有效
        
2.2 定义类中的属性和方法
        --- 给实例定义属性和实例定义方法
    (1) 定义实例方法
            --- 在类中定义的self,代表当前对象
    eg.
    class Person:
        # 类属性
        desc = '人的描述'
        # 类方法
        @classmethod
        def copy_person(cls, old):
            print('类方法执行')
            return cls(old.name, old.age)
            
        # init实例初始化方法---简化对象初始化
        def __init__(self, name, age):
            print('执行init方法')
            # 定义实例属性,弱类型用None
            self.name = 'name'
            self.age = age
            self.weight = None
        # 定义实例方法
        def fun(self, place):
            # wei还没有赋值
            print('{}在{}跑步中,她{}岁,'.format(place, self.name, self.age))
    
    # 强类型属性
    p1 = Person('张珊', 23)
    # 弱类型属性
    p1.wei = 90
    # 复制对象
    p2 = Person.copy_person(p1)
    
    (2) 定义实例属性
        --- 推荐统一在init实例方法中定义,init方法中初始化属性,但不是创建
        注意: init方法添加的属性一定要是强类型属性
        
    (3) 类的成员
        实例属性 实例方法
        类属性   类方法
        静态方法
    
        1> 类属性:   和对象无关,和实例相关 --- 所有实例共有
        2> 实例属性: 和实例无关,和对象相关 --- 所有实例共有
        
        eg.
        class Person:
            # 类属性
            desc = '人的描述'
            # 初始化
            def __init__(self, name, age):
                delf
                
        ① 访问方式:
            实例属性:  a 实例.实例属性
            类属性:    b 类.类属性(推荐)      
                        c 实例.类属性
            
            eg.
            p1 = Person('张珊')
            print(Person.desc)
            print(p1.desc)
            
        ② 修改
            类.类属性       可以修改
            实例.实例属性   不能修改,只会在实例下创建一个新的实例属性
            
            eg.
            p1 = Person('张珊')
            Person.desc = '人的描述_new:'     # 通过类访问
            p1.desc = '人的描述_new:'        # 通过对象访问
            p2 = Person('Geoffrey')
            print(Person.desc, p1.desc, p2.desc)
            
            > 类属性的应用: 定义所有对象都共用的属性
            eg.
            class Pubclass:
            
                department = '光环'
                def __init__(self, name):
                    pass
                    
        3> 实例方法
            --- 跟实例相关,和类无关 ,实例独享 
                
        4> 类方法
            --- 和实例无关,跟类有关,实例共享
                添加装饰器@classmethod

        ① 访问方式:
            类方法访问:         类.方法              实例.方法
            实例方法访问:        实例.方法        类.方法(不推荐)
        
        ② 应用:
            创建、 复制对象
            
    (4) 类属性和实例属性的相互调用
    eg.
    class Person:
        # 类属性
        desc = '人的描述'
        # 类方法
        @classmethod
        def copy_person(cls, old):
            print('类方法执行')
            return cls(old.name, old.age)
        # 静态方法
        @staticmethod
        def makefriend(p1, p2):
            函数体
            print('{}和{}是死对头'.format(p1, p2))
            print('静态方法执行')    
        # init实例初始化方法---简化初始化对象
        def __init__(self, name, age):
            print('执行init方法')
            # 定义实例属性,弱类型用None
            self.name = 'name'
            self.age = age
            self.weight = None
        # 定义实例方法
        def fun(self, place):
            # wei还没有赋值
            print('{}在{}跑步中,她{}岁,'.format(place, self.name, self.age))
            
    ① 类方法   访问 类属性        
        > Person.desc 
        > cls.desc(推荐)
    ② 实例方法 访问 类属性
        > Person.desc
        > self.__class__.desc(推荐)
    ③ 类方法   访问 实例属性
        > 不合理, 类方法不能针对单独实例,(但是不是不能,加参数)
    ④ 实例方法 访问 实例属性
        > 使用self
        
    (3) 静态方法
        --- 相当于类外面的函数,放在了类体里(面向对象)
        @staticmethod
        def sm():
            print('静态方法执行')
    > 静态方法的访问 --- 通过类名
        Person.sm
    > 应用场景:
        ---静态方法只是定义在类的内部,从逻辑结构上,与当前类划分到了一起,从功能的角度讲,我们完全可以将静态方法迁移到类的外部,作为函数来实现同样的功能。
        
总结 --- 类和实例的选择:
1. 类属性 和 实例属性:    
    分析是所有对象共享还是单独对象独享
2. 类方法、实例方法、静态方法:
    分析方法是为什么属性服务,如果是操作实例,定义成实例方法...
                              如果单独作用,静态方法
    
    (4) 魔法方法
        格式: __XXX__
        > 当符合条件时,自动调用
        > 一般不自己创建,因为不能自动调用
        
    ①  __new__(cls, *args, **kwargs) 
        --- 静态方法,且不需要用staticmethod装饰器
            在创建对象时候执行
            在方法中必须有return,否则init方法无法初始化,不能创建对象
        
        eg.
        class Person:
            def __init__(self, name, age):
                print('执行init方法')
                # 定义实例属性,弱类型用None
                self.name = 'name'
                self.age = age
            # __new__已经继承了object,实际为重写
            def __new__(cls, *args, **kwargs)
                # 继承
                return super().__new__(cls)
            def __str__(self):
                print('修改了__str__方法')
                return 'name:{},age:{}'.format(self.name, self.age)
            def __bytes__(self):
                return b'bytes person class'
        p1 = Person()
        print(p1) 相当于 print(p1.__str__())
    ②  __init__ (self)
            --- 实例方法,初始化对象
                
    ③ __del__   
            --- 实例方法,当启动垃圾回收机制回收对象时调用
            
    ④ __str__  
            --- 实例方法,调用内建函数如str,format或print时,返回的str描述
    
    ⑤ __rper__
            --- 和__str__方法相同,但是更接近机器,优先级低于__str__;
            用来以字节的形式描述对象
    ⑥ __bytes__
            --- 转化为字节,用来以字节的形式描述对象
            
    (5) 动态属性操作
    ① hasattr(obj, name)
        --- 判断obj对象中是否已经存在(name)属性名,返回bool
    ② setattr(obj, name, value)
        --- 将obj的name属性赋值value
    ③ getattr(obj, name)
        --- 将obj对象中的name属性取出
    ④ delattr(obj, name)

猜你喜欢

转载自blog.csdn.net/u010359398/article/details/81178092