python类属性

类属性
  类属性是类的属性,此属性属于类,不属于此类的实例
  作用:
    通常用来存储该类型创建的对象的共有属性
  说明:
    类属性可以通过该类直接访问
    类属性可以通过类的实例直接访问
    类属性可以通过此类的对象的__class__属性间接访问

  # 此示例示意类属性
  class Human:
    '''人类'''
    total_count = 0 # 创建类属性,用来保存人类的个数

  print(Human.total_count) # 0 # 类属性可以用类来直接访问 
  Human.total_count += 100 # 修改类属性
  print(Human.total_count) # 100
View Code

类的文档字符串
  类内第一个没有赋值给任何变量的字符串为类的文档字符串
  类的文档字符串可以通过help函数查看
  类的文档字符口中 可以用类的__doc__属性访问

  示例:
  class Dog:
  '''这是用来描述小狗类型对象的类

    此类有三个方法,吃,睡,玩...'''
    pass
View Code

类的 __slots__列表
  作用:
    限定一个类创建的实例只能有固定的实例属性(实例变量)
    不允许对象添加一个列表以外的实例属性(实例变量)
    防止用户因错写属性的名称而发生程序错误
  说明:
    __slots__属性是一个列表,列表的值是字符串
    含有 __slots__ 列表的类所创建的实例对象没有__dict__属性即此实例不用字典来存储对象的实例属性

  class Human:
    '''让Huam类型的对象只能有name 和 age属性,
    不能有其它属性'''
    __slots__ = ['name', 'age']
    def __init__(self, name, age):
      self.name = name
      self.age = age
    def show_info(self):
      print("姓名:", self.name, '年龄', self.age)

  h1 = Human('小张', 15)
  h1.show_info() # ??? 15
  # h1.ago = 16 # 主动报错
  h1.show_info() # ??? 15
View Code

类方法 @classmethod
  类方法是用于描述类的行为的方法,类方法属于类,不属于该类创建的对象

  说明:
    类方法需要使用@classmethod装饰器定义
    类方法至少有一个形参,第一个形参用于绑定类,约定写为'cls'
    类和该类的实例都可以调用类方法
    类方法不能访问此类创建的对象的实例属性

  class A:
    v = 0 # 类属性

    @classmethod
    def get_v(cls):
      '''类方法'''
      return cls.v

    @classmethod
    def set_v(cls, value):
      cls.v = value

  print(A.v)
  A.set_v(888) # 用类来调用类方法
  print(A.get_v()) # 888 用类来调用类方法
  a = A()
  print(a.get_v()) # 888 用对象来调用类方法
  a.set_v(999) # 用实例对象来调用类方法
  print(A.get_v()) # 999
  print(a.get_v()) # 999
View Code

静态方法 @staticmethod
  静态方法是定义在类内部的函数,比函数的作用域是类的内部

  说明:
    静态方法需要使用@staticmethod装饰器定义
    静态方法与普通函数的定义相同,不需要传入self实例参数和cls 类参数
    静态方法只能凭借该类或类创建的实例调用
    静态方法不能访问类属性和实例属性

  class A:
    @staticmethod
    def myadd(a, b):
      return a + b

  print(A.myadd(100, 200))
  a = A()
  print(a.myadd(3, 4))
View Code

继承(inheritance) 和 派生(derived)
  继承是从一个已有的类中派生出新类,新类具有原类的数据属性和行为并能扩展新的行为
  继承的目的是延续旧的类的功能
  派生的目的是在旧类的基础上添加新的功能
  作用:
    用继承派生机制,可以将一些共有功能加在基类中,实现代码的共享

    在不改变基类代码的基础上改变原有类的功能
  名词:
    基类/超类/父类
    派生类/子类

  单继承的语法:
    class 类名(基类名):
      语句块
  单继承是指派生类有一个基类衍生出来的

  class Human:
    def say(self, what):
      print("say:", what)
    def walk(self, distance):
      print("走了", distance, '公里')

  class Student(Human):
    def study(self, subject):
      print("正在学习:", subject)

  class Teacher(Student):
    def teach(self, subject):
      print("正在教", subject)

  h1 = Human()
  h1.say("天气变暖了")
  h1.walk(6)

  s1 = Student()
  s1.walk(4)
  s1.say('有点小累')
  s1.study('Python')

  t1.teach("面向对象")
  t1.walk(3)
  t1.say('晚上吃点啥呢?')
  t1.study('转魔方')
View Code

继承说明:
  Python3类都直接或间接的继承自object类
  object类是一切类的超类

类的__base__属性
  __base__属性用记录此类的基类

内建的类的继承关系见:
  >>> help(__builtins__)

覆盖 override
  覆盖是指在有继承关系的类中,子类中实现了与基类同名的方法,在子类的实例调用该方法时,实际调用的是子类中的覆盖版本,这种现象叫覆盖

  作用:
    实现和父类同名,但功能不同的方法

 

  class A:
    def work(self):
      print("A.work被调用")

  class B(A):
    def work(self):
      '此方法覆盖了A.work方法'
      print("B.work被调用!")

  b = B()
  b.work() # B.work
  a = A()
  a.work() # A.work
View Code

问题:
  当覆盖发生时,子类对象能否调用父类的方法呢?

调用方式:
  基类名.方法名(实例, 实际调用参数, ...)

super函数
  super(cls, obj) 返回绑定超类的实例(要求obj必须是cls类型的实例)
  super() 返回绑定超类的实例,等同于:super(__class__, 实例方法的第一个参数)(必须在方法内调用)
  作用:
    借助super()返回实例间接调用其父类的覆盖方法

 

  class A:
    def work(self):
      print("A.work被调用")

  class B(A):
    def work(self):
      '此方法覆盖了A.work方法'
      print("B.work被调用!")
    def super_work(self):
      self.work() # 调用自己的
      super(B, self).work()
      super().work() # 功能等同于上一句
  b = B()
  b.super_work()
  # b.work() # B.work被调用!
  # A.work(b) # A.work被调用
  # super(B, b).work()
View Code

显式调用基类的初始化方法:
  当子类中实现了__init__方法,基类的初始化方法并不会被调用此时需要用super来显式调用

  class Human:
    def __init__(self, n, a):
      self.name = n # 姓名
      self.age = a # 年龄
      print("Human.__init__方法被调用")
    def infos(self):
      print("姓名:", self.name)
      print("年龄:", self.age)

  class Student(Human):
    def __init__(self, n, a, s=0):
      super().__init__(n, a) # 显式调用父类的初始化方法
      self.score = s
      print("Student.__init__被调用!")
    def infos(self):
      super().infos() # 显式调用父类的infos()
      print("成绩:", self.score)

  s = Student("小张", 20)
  s.infos()
View Code

用于类的函数:
  issubclass(cls, class_or_tule) 判断一个类是否继承自其它的类,如果此类class是class 或tuple中的一个派生子类则返回True, 否则返回False

  如:
  class A:
    pass

  class B(A):
    pass

  class C(B):
    pass

  issubclass(C, B) # True
  issubclass(C, A) # True
  issubclass(A, B) # False
  issubclass(bool, (str, A, B, C, float)) # False
  issubclass(bool, (str, float, int)) # True
View Code
posted @ 2019-04-13 20:53  你厉害。  阅读(506)  评论(0编辑  收藏  举报