静态方法,类方法和实例方法

类属性和实例属性

  • 实例属性:每个对象 自身固有的属性我们声明为实例属性,在实例对象中定义的属性(__init__中定义的属性)

  • 类属性:每个对象 自身固有的属性我们声明为实例属性,在类中定义的属性(类里面,方法外面),多个实例对象共享一份类属性

  • 实例属性的声明和访问

    • 声明:实例属性的声明,包含在类型中的__init__()初始化方法中,使用 self 关键字将属性绑定到当前对象上

      <pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" cid="n12" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit;" lang="python"> def init(self,name,age):
      """实例属性初始化"""
      self.name=name
      self.age=age</pre>

    • 访问:实例属性在类型内部可以通过self关键字引用,在类型外部可以通过对象引用变量访问和修改

      <pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" cid="n15" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit;" lang="python"> class User:
      def init(self,name,age):
      """实例属性初始化"""
      self.name=name
      self.age=age
      user = User("zs",18)
      print(user.name)</pre>

  • 类属性的声明和访问

    • 声明:类里面,方法的外部

      <pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" cid="n21" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit;" lang="python"> #数据类
      class Data:
      """数据的类型"""
      course_dict = {} #键:课程名称,值:课程对象

      使用实例对象访问

      data = Data()
      print(data.course_dict)

      使用类对象访问

      print(Data.course_dict)</pre>

    • 访问:类属性可以被当前类的所有对象访问,或者直接通过类访问

  • 类属性的修改

    • 类属性只能通过类名称引用修改,不能通过实例对象修改

    • 1.不可变类型:对象名.属性名=属性值 给对象添加属性,而不是进行修改

    • 2.可变类型:如果对象是修改可变数据类型,是真正的修改

      如果是重新给可变类型赋值,则是给对象添加属性

    <pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" cid="n34" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit;" lang="python"> class Data:
    """数据类"""

    course_data = "python"

    course_data = ["python"]
    data = Data()

    使用类对象修改课程为“java”

    Data.course_data = "java"

    使用实例对象访问

    print(data.course_data)

    使用类对象访问

    print(Data.course_data)

    使用实例对象修改课程为“UI”

    data.course_data = "UI" #实际上是给实例对象增加属性

    使用实例对象访问

    print(data.course_data)

    使用类对象访问

    print(Data.course_data)

    如果类属性是可变数据类型,则是真正的修改

    添加课程“java”

    使用类对象添加

    Data.course_data.append("java")

    使用实例对象添加

    data.course_data.append("java")

    使用实例对象访问

    print(data.course_data)

    使用类对象访问

    print(Data.course_data)

    实例对象给可变数据类型重新赋值,则是给该对象添加属性

    data.course_data = ["python","java"]

    使用实例对象访问

    print(data.course_data)

    使用类对象访问

    print(Data.course_data)</pre>

  • 总结:

    • 1.类可以调用实例方法,静态方法,类方法和类属性,但是不能调用实例属性

    • 2.实例对象可以调用实例方法,类方法,静态方法,类属性,实例属性

      实例对象可以调用所有属性和方法,类除了不能调用实例属性,其他方法和属性都可以调用

静态方法、类方法和实例方法

  • 1.实例方法

    • 在类中定义的普通方法,在实例化对象之后使用,该方法接收的第一个参数一定是对象本身

      <pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" cid="n50" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit;" lang="python"> class User:
      def introduce(self):
      print("这是实例方法中的代码")
      user = User()

      通过对象调用实例方法

      user.introduce()</pre>

  • 2.类方法

    • 声明在类的内部,方法上使用装饰器 @classmethod

    • 第一参数是当前类型本身,约定俗称cls, 类方法执行访问当前的类属性,不能访问任何对象的实例属性

    • 类方法可以被当前类型调用,也能被实例对象调用

    • 使用场景:当一个方法中只涉及静态属性的时候可以使用类方法(类方法可以修改类属性)

  • 3.静态方法:是被同意管理在类中的函数,声明在类的内部

    • 1.格式:方法上添加@staticmethod

    • 2.参数:静态方法可以有参数,也可以无参数

    • 3.应用场景:一般用于和类以及实例对象无关的代码

    • 使用方法:类名.方法名() 或者对象名.方法名()

  • 总结:

    • 如果使用到实例属性或实例方法,我们使用实例方法

    • 如果只涉及到类属性,可以使用类方法

    • 如果不涉及到任何的实例属性或类属性,可以使用静态方法

魔术方法

  • 1.构造方法

    魔术方法 描述
    __new__(cls)方法 创建对象,创建对象时触发
    __init__(self)方法 初始化对象数据,创建完对象触发
  • 2.对象删除方法

    魔术方法 描述
    __del__()方法 对象将要被删除时执行

    <pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" cid="n105" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit;" lang="python"> class User:
    """用户类型"""
    def init(self,name):
    """实例属性初始化"""
    print("init方法初始化")
    self.name = name
    def del(self):
    print("对象将要被删除")
    def func():
    user = User("古印")
    return user
    ret = func()
    print("程序执行结束")</pre>

  • 3.对象打印方法

    魔术方法 描述
    __str__()方法 直接打印对象,自定义返回值(字符串)
    __repr__()方法 对象在组合数据类型中,打印展示自定义的返回值
  • 4.对象的函数式调用

    魔术方法 描述
    __call__()方法 让对象可以类似函数的方法直接调用执行
  • 5.其他

    魔术方法 描述
    __eq__()方法 定义“==”的操作

反射方法

  • 反射:通过字符串的形式操作对象相关的属性,python中一切都是对象(都可以使用反射)

  • 1.反射类的属性和方法 2.反射对象的属性和方法 3.反射模块中的属性和方法

    反射方法 描述
    hasattr(obj,name) 判断是否包含名称为name的属性,返回的是布尔值
    getattr(obj,name) 获取名称为name的属性的具体数据
    setattr(obj,name) 较少 给名称为name的属性设置value值
    delattr(obj,name) 较少 删除名称为name的属性

    <pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" cid="n158" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit;" lang="python"> getattr()
    class Teacher():
    dic = {"学生信息":"show_student","老师信息":"show_teacher"}

    def init(self,name,age):
    self.name = name
    self.age = age

    @classmethod
    def func(cls):
    print("--func--")
    def show_student(self):
    print("--show student--")
    def show_teacher(self):
    print("--show teacher")
    反射类中的属性和方法
    获取Teacher类中的dic
    print(getattr(Teacher,"dic"))

    获取Teacher类中的func

    ret = getattr(Teacher,"func")
    ret()

    反射对象中的属性和方法
    teacher = Teacher("陈老师",21)
    获取name属性
    print(getattr(teacher,"name")) #teacher.name
    获取所有的属性
    print(getattr(teacher,"dict"))
    ret = getattr(teacher,"show_student")

    print(ret)

    ret()

    反射模块中的属性和方法
    import test1

    反射模块中的属性
    print(getattr(test1,"name"))

    反射模块中 的方法
    func1 = getattr(test1,"func1")
    func1()

    func2 = getattr(test1,"func2")
    func2(666)

    反射模块中的类
    Person = getattr(test1,"Person")
    per = Person()
    per.study()</pre>

    <pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" cid="n159" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit;" lang="python"> # hasattr() 检测对象是否有某个成员,返回布尔
    class Teacher():
    dic = {"学生信息":"show_student","老师信息":"show_teacher"}
    def init(self,name,age):
    self.name = name
    self.age = age
    @classmethod
    def func(cls):
    print("--func--")
    def show_student(self):
    print("--show student--")
    def show_teacher(self):
    print("--show teacher")

    判断有没有dic

    b = hasattr(Teacher,"dic")
    if b:
    ret = getattr(Teacher,"dic")
    print(ret)
    else:
    print("没有此属性")

    练习:根据用户输入的key来调用对应的方法

    如:输入“学生信息”,调用 show_student

    key = input("请输入学生信息或老师信息:") #学生信息
    "--show student--"</pre>

    <pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" cid="n160" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit;" lang="python"> #setattr 给对象或者类添加属性
    class Person:
    pass

    给Person添加静态属性age

    setattr(Person,"age",18)

    print(Person.age)

    delattr 删除对象或者类中的成员

    per = Person()
    setattr(per,"name","黄志")

    print(per.name)

    delattr(Person,"age")
    print(Person.age)</pre>

单例模式

  • 单例模式确实某一个类只有一个实例存在

  • 当你希望在整个程序中,某个类只能出现一个实例时,就可以使用单例模式

  • 方法:是否是第一次创建对象,如果是首次创建对象,则调用父类__new__()方法创建对象并返回

    如果不是第一次创建对象,直接返回第一次创建的对象即可

    <pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" cid="n170" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit;" lang="python"> ​

    是否是第一次创建对象,如果是首次创建对象,则调用父类__new__()方法创建对象并返回

    如果不是第一次创建对象,直接返回第一次创建的对象即可

    class ShoppingCart:

    instance = None #记录创建的对象,None说明是第一次创建对象

    def new(cls, *args, **kwargs):

    #第一次就调用new方法,创建对象并记录

    #第2-n次调用new方法,不创建对象,而是直接返回记录的对象

    #判断是否是第一次创建对象

    if cls.instance==None:

    cls.instance = object.new(cls) #创建对象并记录

    return cls.instance

    else: #如果不是第一次创建对象

    return cls.instance

    shop1 = ShoppingCart()

    shop2 = ShoppingCart()

    print(shop1,shop2)

    class ShoppingCart:

    instance = None #记录创建的对象,None说明是第一次创建对象

    def new(cls, *args, **kwargs):

    #第一次就调用new方法,创建对象并记录

    #第2-n次调用new方法,不创建对象,而是直接返回记录的对象

    #判断是否是第一次创建对象

    if cls.instance==None:

    cls.instance = object.new(cls) #创建对象并记录

    return cls.instance

    shop1 = ShoppingCart()

    shop2 = ShoppingCart()

    print(shop1,shop2)


    class ShoppingCart:
    def new(cls, *args, **kwargs):
    if not hasattr(cls,"instance"): #如果cls没有instance,则创建对象并记录
    cls.instance = object.new(cls)
    return cls.instance
    shop1 = ShoppingCart()
    shop2 = ShoppingCart() #第二次创建对象时,已有类属性instance
    print(shop1,shop2)</pre>

[图片上传失败...(image-5c46af-1595502797873)]

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容