zoukankan      html  css  js  c++  java
  • 第八天

    类与对象
    一、什么是类、对象
    1. 什么是对象:对象(实例),万物皆对象,对象是具有属性和行为的。
    举例:桌子,椅子,你,你同桌,小猫,小狗。。
    属性:桌子:颜色、四个腿、有没有桌洞。。。名词
    行为:猫:叫,吃饭,睡觉,打豆豆 动词

    2. 什么是类
    一个类别,按照某种需求划分的类别。
    具有相同的属性和行为的对象,构成一个整体----类
    分类规则:按照需求,不是所有的分类都是一个样子

    举例:学生管理系统,学生,老师
    公交卡系统,学生和老师?是一个分类 人和公交车,票,站台

    3. 类和对象之间的关系
    类是对象的抽象,对象是类的具体实现。
    类:看成是模板,蓝图,设计图纸
    对象:看成设计出来实际的实例

    举例,生产汽车,Car 类(属性:颜色、牌子、尺寸、座椅)
    (行为:运动档。。。)
    奥迪--Car(颜色=黑色,牌子=奥迪,尺寸=2米,座椅=真皮)
    (行为:运动档,自动)
    总结:一个对象至少有类的属性和行为,才能称为是这个类的对象。
    学生管理系统:定义一个python讲师,Student产生对象?Teacher产生对象?


    二、 类的定义和初始化
    1. 类的定义
    格式:class 类名
    '注释':不是必须的,开发好习惯
    类体

    类名:习惯是首字母大写
    """
    # 定义一个人的类
    # class Person:
    # '这是一个人的类'
    # pass
    # 可以使用类产生(创建)对象
    # 语法 对象名=类名()--------本质上就是在调用类里面的创建对象的函数
    # p1=Person()
    # print(p1)
    # print(p1.__doc__)

    2. 定义属性和方法
    # 属性:以变量赋值的方式存在
    # 行为:以方法(函数)的形式存在

    (1). 动态的属性和方法(都是给对象的)
    # 属性:动态属性,就是简单的变量赋值,如果当前的对象已经有这个属性了,
    # 那么会覆盖(其实只是变量绑定修改了,不是真正删除了),如果没有,则会新建
    # 对象名.属性名
    # p1.name="张三"
    # print(p1.name)
    # p1.name="张三丰"
    # print(p1.name)
    # 动态定义属性,缺点:只对于某一个对象有作用,对于其他对象是不起作用的
    # p2=Person()
    # print(p2.name)

    # 行为:在类的外面定义函数
    def run(self):
    print("我在跑步")
    # self 代表 参数代表当前对象自己,run方法属于哪一个对象,self就是那个对象
    # 给某一个类定义行为的时候,必须要self方法,
    # 在类的外面调用的时候,必须传入self
    # 在类的里面调用,则不用传入

    # 把行为给一个对象:对象名.行为名=函数名
    # p1.run=run
    # 调用,对象.行为(对象)
    # p1.run(p1)
    # p2=Person()
    # p2.run=run
    # p2.run(p2)

    # 动态的属性和方法的局限:每一个对象都有单独被赋予属性和方法才可以使用

    (2) 在类中定义属性和方法(必须掌握)
    # 方法:是定义在类里面
    # 给类定义行为(函数),必须有self这个参数。

    # class Person:
    # def run(self):
    # print("我在跑步")
    # # 希望调用类下面的实例方法(行为),必须先有对象
    # p1=Person()
    # p1.run() # 在类下面定义行为的时候,调用时,不需要显式的传入self参数
    #
    # p2=Person()
    # p2.run()

    # 定义属性
    # 类里面,对象的初始化方法 __init__:在创建对象时,自动调用的方法
    # init 方法每创建一次,都会执行一次
    # class Person:
    # def run(self):
    # print("我在跑步")
    # def __init__(self):
    # self.name="张三"
    # self.age=20
    # print("在执行__init__方法")
    # p1=Person()
    # print(p1.name)
    # print(p1.age)
    #
    # p2=Person()
    # print(p2.name)
    # print(p2.age)

    # 解决不是所有的对象的name都一样的问题
    class Person:
    # 在自定义的方法中也可以获得对象的属性
    def run(self,place):
    print("我{}{}在{}跑步".format(self.name,self.age,place))
    def __init__(self,name,age):
    self.name=name
    self.age=age
    print("在执行__init__方法")
    p1=Person("张三",20)
    print(p1.name)
    print(p1.age)
    p1.run("操场")

    p2=Person("李四",40)
    print(p2.name)
    print(p2.age)
    p2.run("公园")

    """
    1.创建一个"狗"的类
    2.定义对象的共有属性 name age type(类型)
    3.定义对象的共有行为:
    叫,可以获得狗的名字
    吃饭,可以传入狗粮的牌子
    睡觉
    4.定义对象的特殊属性(不是所有对象共有),对产生的某一个对象定义出生地
    """
    class Dog:
    '这是一个狗狗的分类'
    def __init__(self,name,age,type):
    self.name=name
    self.age=age
    self.type=type
    print('{} {}岁 品种:{}'.format(self.name,self.age,self.type))
    def rowl(self):
    print("{}在叫".format(self.name))
    def eat(self,brand):
    print("{}在吃{}牌子的狗粮".format(self.name,brand))
    def sleep(self):
    print("{}在睡觉".format(self.name))
    d1=Dog("大黄",3,"狼狗")
    d1.rowl()
    d1.eat("单身")
    d1.sleep()
    d1.place="火星"
    print("{}出生在{}".format(d1.name,d1.place))
    print(" ------------------- ")
    d2=Dog("sanmo",2,"阿拉斯加")
    d2.rowl()
    d2.eat("NexGard")
    d2.sleep()
    d2.place="阿拉斯加"
    print("{}出生在{}".format(d2.name,d2.place))

    三、类的成员
    """
    类属性,类方法
    实例属性,实例方法
    静态方法
    """
    1. 类属性和 实例属性
    # 实例属性:跟对象相关,对象属性
    # 类属性:跟类关联,不属于任何一个对象、类属性直接定义在类体(变量赋值的形式)

    """
    分析类属性和实例属性的不同
    (1) 属性的绑定不同
    类属性:绑定跟当前的类相关,产生的任何一个对象都跟类属性没有任何关系
    所有的对象都可以访问这个属性,公用的,共享
    实例属性:跟每一个对象都有关系的属性
    每一个对象独有,不共享
    (2) 访问方式不同
    类属性:访问方式有两种,一种是可以通过类名访问:类名.类属性(可读可写)
    另外一种,可以对象.类属性访问(只能访问,不能修改)
    实例属性:对象(实例).属性,会通过实例访问。不能通过类去访问
    """
    class Person:
    # 类属性
    desc="人的描述"
    def __init__(self,name):
    # 实例(对象)属性
    self.name=name
    # 访问实例属性
    # p1=Person("张三")
    # print(p1.name)
    # p2=Person("李四")

    # 访问类属性
    # 第一种方式,通过类访问,可以访问和修改
    # print(Person.desc)
    # Person.desc="=人的描述_new"
    # print(Person.desc)
    # 第二种方式,通过对象访问,不能修改
    # print(p1.desc)
    # print(p2.desc)
    # p2.desc="人的描述_new_new"
    # print(p2.desc) # 使用对象.类属性的形式修改类属性,其实不是修改,而是新建了一个属性
    # print(Person.desc)

    # 类属性的应用:定义所有对象共有的属性
    # 建议访问类属性,只使用【类.类属性】
    # 练习:注意实例属性属于每一个对象。跟类没关系
    # p3=Person("王五")
    # p4=Person("赵六")
    # p3.name="王五五"
    # print(p3.name)
    # print(p4.name)

    2. 类方法和实例方法
    # (1) 实例方法:跟具体的每一个对象关联的方法。
    # 类方法:跟类相关联的方法,跟每一个对象没有关系
    # (2) 类方法的定义:在类里面写方法,加标记(装饰器)@classmethod修饰
    # (3) 访问方式

    # 类方法:两种形式
    # 类名.类方法(建议方式)
    # 对象.类方法
    # 实例方法:
    # 对象.实例方法
    # 类.实例方法
    class Person:
    desc="人的描述"
    def __init__(self,name):
    self.name=name
    def run(self):
    print("跑步")
    @classmethod
    def cm(cls):
    # cls指当前类
    print("类方法")
    print(cls is Person) # 证明是不是当前类
    @classmethod
    def copy(cls,p):
    return cls(p.name)
    # 应编码
    # return Person("张三")
    # Person.cm()
    # p1=Person("张三")
    # p1.cm()
    # p2=Person.copy(p1)
    # print("p2的name",p2.name)
    # Person.run(p1) # 通过类也能访问到实例方法,但是不建议

    # 类方法的应用:复制对象,通过一个已有对象,返回跟当前对象一样的一个新对象

    3. 类方法和实例方法中对实例属性和类属性进行访问
    # (1) 实例方法调用实例属性
    class Person:
    def __init__(self,name):
    self.name=name
    def walk(self):
    print(self.name+"正在走路")
    p1=Person("张三")
    p1.walk()

    p2=Person("李四")
    p2.walk()

    # (2) 类方法调用类属性
    class Person:
    desc="人的描述"
    @classmethod
    def cm(cls):
    cls.desc="人的描述_new"
    print(Person.desc)
    Person.cm()
    print(Person.desc)

    # (3) 实例方法调用类属性
    class Person:
    desc="人的描述"
    def walk(self):
    # 使用self对象,只能对类属性进行访问,不能修改
    print(self.desc)
    # __class__ 获得当前对象所属的类,可以通过他访问属性,修改类属性
    print(self.__class__.desc)
    self.__class__.desc="人的描述_new"
    print(self.__class__.desc)
    print(self.desc)
    print("正在走路")
    p=Person()
    p.walk()
    # (4) 类方法调用实例属性
    # 一般来说不这么用
    class Person:
    def __init__(self,name):
    self.name=name

    @classmethod
    def cm(cls,p):
    print(p.name)
    p=Person("张三")
    Person.cm(p)

    4. 静态方法
    # 在类中定义的方法:静态方法跟类没关系,跟实例更没关系,一般用来给类服务。
    # 调用的时候,使用类调用
    # 用法
    """
    @staticmethod
    def 静态方法的名字:
    方法体
    """
    class Person():
    def __init__(self,name):
    self.name=name
    @staticmethod
    def s_m():
    print("这是静态方法")
    @staticmethod
    def makeFriend(p1,p2):
    print("{}和{}交朋友".format(p1.name,p2.name))

    # 访问:建议使用【类.静态方法】
    Person.s_m()
    p=Person()
    p.s_m()

    # 静态方法的应用:实现两个对象之间的关系。
    p1=Person("张三")
    p2=Person("李四")
    Person.makeFriend(p1,p2)

    """
    类和实例的选择
    类属性、类方法、静态方法
    实例属性、实例方法

    【类属性、实例属性的选择】
    属性是所有对象共享的,还是单对象独享,如果是共享,就应该定义成类属性,如果是独享的,就应该定义成实例属性

    【实例方法、类方法、静态方法的选择】
    方法的目的:为了对类中属性进行操作
    当定义的方法是对实例或者实例的属性进行操作的,那么应该定义成实例方法
    如果定义的方法操作的是类属性,应该定义成类方法
    如果定义的方法跟对象没多大关系,跟类也没多大关系,完全可以拿到类的外面,只是为了类服务的,定义成静态方法
    """

    四、魔法方法
    # 在python中定义的特殊的方法,格式__xx__ 命名规则
    # 魔法方法不需要主动调用,也不需要显示的调用,当符合一定条件的时候,自动调用

    1. __new__(cls):
    # 类方法,在创建对象的时候,自动执行,是真正的创建对象的方法
    # new是类方法,但是定义的时候不需要使用classmethod修饰
    class Person():
    def __new__(cls):
    print("new 方法")
    # 在创建的 任何一个类里面,已经继承了object类
    return super().__new__()
    # def __init__(self):
    # print("init 方法")
    # p=Person("aa",20)
    # print(p)

    2. __init__(self),在new方法后面,对创建的对象进行初始化
    # 对对象的属性进行初始化
    # 在new方法中如果有return才会执行init,如果没有return则不会执行init

    3. __del__(self),当对象销毁的时候,会自动调用的方法
    class Person:
    def __new__(cls):
    print("new 方法")
    # 在创建的 任何一个类里面,已经继承了object类
    return super().__new__()
    def __init__(self):
    print("init 方法")
    def __del__(self):
    print("执行del方法")

    p=Person()
    # # 如果在删除对象之前,给对象赋予新的变量,del不能删除当前对象
    # p2=p
    # print("删除p之前")
    # del p
    # print("删除p之后")

    4. __str__(self):实例方法 相当于调用内建函数中的str 或者format,print时候,会自动把对象转换成字符串
    class Person:
    def __new__(cls):
    print("new 方法")
    return super().__new__()
    def __init__(self,name,age):
    self.name=name
    self.age=age
    print("init 方法")
    def __del__(self):
    print("执行del方法")
    def __str__(self):
    s="属性:name={};age={}".format(self.name,self.age)
    return s
    def __repr__(self):
    return "<Person class>"
    def __bytes__(self):
    return b"byte person class"
    p=Person("张三",20)
    print(p)
    print(str(p))
    print(repr(p))

    5.__repr__(self):实例方法,返回str类型的对象,repr是对解释器友好,str是对人友好
    # 当程序中 没有定义str方法,却调用了str方法,python会去找repr

    6. __bytes__(self):相当于调用bytes方法,返回字节类型,以字节类型描述对象
    print(bytes(p))


    7. __call__(self):可以把对象当成函数一样调用
    class Person:
    def __init__(self,name,age):
    self.name=name
    self.age=age
    print("init 方法")
    def __call__(self):
    print("call 方法")
    p=Person("张三",20)
    p()

    五、 动态属性的操作
    1. hasattr(obj,name):判断obj对象中是否存在name属性,返回True,False
    class Person:
    pass
    p=Person()
    p.name="张三"
    print(hasattr(p,"name"))
    print(hasattr(p,"age"))

    2.setattr(obj,name,value)设置属性的值
    setattr(p,"age",20)
    print(p.age)

    3.getattr(obj,name,default)返回属性的值
    print(getattr(p,"age"))
    print(getattr(p,"age1",5))

    # 删除
    delattr(p,"age")

    # 动态设置属性的操作是3个内置方法,主要用来动态的给对象进行赋值
    p.gender="男"
    print(p.gender)

    # 通过键盘输入,设置属性名和属性值
    aname=input("输入属性名")
    avalue=input("输入属性值")

    setattr(p,aname,avalue)
    print(getattr(p,aname))


  • 相关阅读:
    PostgreSQL数据库逻辑复制实践
    CentOS7通过yum安装postgreSQL
    MongoDB动态建表方案(官方原生驱动)
    7大常用开源数据库利弊全对比
    错误:由于系统时间错误证书验证失败导致更新不成功
    deppin更新提示“由于没有公钥,无法验证下列签名”
    Debian 9 Vim无法使用鼠标右键复制 解决方法
    PHP版滑动时间窗口算法
    RabbitMQ PHP 代码示例
    创建或修改 docker 容器内部文件
  • 原文地址:https://www.cnblogs.com/ztx695911088/p/9074716.html
Copyright © 2011-2022 走看看