Python人工智能从入门到精通
补充:
实例方法都是操作实例对象的 属于此类对象的方法
实例变量
添加/修改属性:
对象.属性名 = 表达式
删除:
del 对象.属性名
类 | 对象 | 实例
class object instance
类的本质上也是对象 类可以创建此类对象
-----------------------------------------------------------------------------------------------------------------
类:
类变量:
类变量是类的属性, 此属性属于类, 不属于此类的实例
作用:
通常用来储存该类创建的对象的共同属性
说明:
类变量可以通过该类的实例直接访问
类变量可以通过类的实例间接访问
类变量可以通过此类的对象__class__属性间接访问
示例:
# -*- coding:utf-8 -*- # 类变量 class Human: total_count = 0 # 类变量 def __init__(self, name): print(name, '对象被创建') print(Human.total_count) # 0 h1 = Human("zhang") print(h1.total_count) # 0 用此类实例访问类变量 h1.total_count = 100 # 为对象添加实例变量 print(h1.total_count) # 100 优先访问实例变量 print(Human.total_count) # 0 访问类变量 class Human: total_count = 0 # 类变量 def __init__(self, name): print(name, '对象被创建') h1 = Human("zhang") print(Human.total_count) # 0 h1.__class__.total_count = 100 # 为类添加修改实例变量 print(h1.total_count) # 100 间接访问类变量 print(Human.total_count) # 100 访问类变量 # 类变量的应用 用类变量记录实例个数 class Human: total_count = 0 # 类变量 def __init__(self, name): print(name, '对象被创建') self.__class__.total_count += 1 # 每次创建对象调用__init__ 类变量加1 def __del__(self): self.__class__.total_count += 1 # 每次析构对象后类变量减1 h1 = Human("zhang") print("此时Human对象的个数是", Human.total_count) # 1 L = [] L.append(Human("li")) L.append(Human("zhao")) print("此时Human对象的个数是", Human.total_count) # 3 del h1 L.pop() print("此时Human对象的个数是", Human.total_count) # 1
类的文档字符串:
和函数等一样
用__doc__属性访问
示例:
>>> class Dog: ... '''这是小动物''' ... >>> help(Dog) >>> Dog.__doc__ '这是小动物' >>>
类 __slots__ 列表:
作用:
限定一个类的创建实例只能有固定的属性(实例变量)
不允许对象添加列表以外的属性(实例变量)
防止用户因错写属性的名称而发生错误
说明:
1.__slots__ 列表绑定一个字符串列表
2.含有__slots__列表的类所创建的实例对象没有__dict__属性
(不用字典储存对象的属性 __slots__限制)
示例:
class Human: # 以下列表限制此类对象只能有这两个属性 防止出错 __slots__ = ["name", "age"] def __init__(self, name, age): self.name, self.age = name, age h1 = Human("Ta", 15) print(h1.age) # 15 h1.Age = 18 # 区分大小写 出错 没有Age属性,也不允许有 print(h1.age) # 15
类方法 @ classmethod
类方法是用于描述类的行为的方法 类方法属于类, 不属于类的实例
说明:
类方法需要使用 @classmethod 装饰器定义
类方法至少有一个形参, 第一个形参用于绑定类, 约定写“cls”
类和该类的实例都可以调用类的方法
类方法不能访问此类创建的实例的属性
示例:
# 类方法的使用 class A: v = 0 @classmethod def get_v(cls): # cls 用来绑定调用此方法的类 return cls.v # 访问类变量 @classmethod def set_v(cls, value): cls.v = value print(A.get_v()) # 0 A.set_v(100) print(A.get_v()) # 100 a1 = A() # 创建实例 print("a1.get_v=", a1.get_v) # 100 a1.set_v(200) print("a1.get_v=", a1.get_v) # 200 print("A.get_v=", A.get_v) # 200
静态方法 @staticmethod
静态方法是定义在类内部的函数, 此函数的作用域是类的内部
说明:
静态方法需要使用 @staticmethod 装饰器定义
静态方法与普通函数定义相同, 不需要传入self实例参数和cls参数
静态方法只能凭借该类的创建实例调用
静态方法不能访问变量和实例变量(属性)
示例:
# 静态方法 class A: @staticmethod def myadd(a, b): return a + b print(A.myadd(100, 200)) # 300 a = A() # 创建实例 print(a.myadd(300, 400)) # 700 # def myadd(a, b): # 和静态方法结果一样 # return a + b # class A: # pass # print(A.myadd(100, 200)) # 300 # a = A() # 创建实例 # print(a.myadd(300, 400)) # 700
实例方法, 类方法, 静态方法,函数, 小结:
1.不想访问 类内 的和 实例内 的变量, 用静态方法
2.只想访问类变量, 不想访问实例变量, 用类方法
3.既要访问类变量, 也想访问实例变量, 用实例方法
4.函数与静态方法相同, 只是静态方式的作用域定义在类内
继承inheritance/派生derive:
什么是继承/派生:
继承是从已有的类中派生出新的类, 新类具有原类的行为, 并能扩充新的行为
派生是从已有的类中衍生成新类, 在新类上可以添加新的属性和行为
作用:
用继承派生机制, 可以将一些共有的功能加在基类中, 实现代码的共享
在不改变基类的代码的基础上改变原有的功能
名词:
基类(base class) / 超类(super class)/父类(father class)
派生类(derived class)/子类(child class)
子类对象一定是父类对象的类型
父类对象不一定是子类对象的类型
单继承:
语法:
class 类名(基类名)
语句块
说明:
单继承是指由一各基类衍生出新的类
示例:
# 单继承用法 class Human: # 人类的共性 def say(srlf, what): print("说:", what) def walk(self, distance): # 走路 print("走了", distance, "公里") class Student(Human): # 继承 # def say(srlf, what): # print("说:", what) # def walk(self, distance): # 走路 # print("走了", distance, "公里") def study(self, subject): # 派生 print("学习", subject) class Teacher(Student): def teach(self, subject): # 派生 print("教", subject) h1 = Human() h1.say("哈哈") h1.walk(500) s1 = Student() s1.walk(4) s1.say("666") s1.study("python") T1 = Teacher() T1.walk(4) T1.say("666") T1.teach("python") T1.study("Java")
继承说明:
python3 任何类都可以直接或间接的继承object类
object 类是一切类的超类(父类)
class的继承参数不写, 默认继承object类 一般省略不写
object类的超类是None
类的__base__属性:
__base__ 属性用来记录此类的基类(父类)
Python的内建类:
help(__builtins__)
覆盖 override
覆盖是指在有继承关系的类中, 子类中实现了与基类同名的方法, 在子类
的实例调用该方法时, 实际调用的是子类的覆盖版本, 这种现象叫覆盖
示例:
# 覆盖 override class A: def works(self): print("A.works被调用") class B(A): '''B继承A类''' def works(self): print("B.works被调用") b = B() b.works() # B.works被调用 # B.works 覆盖 A.works 优先调用子类 # A派生B B继承A # 子类对象显示调用基类(被覆盖)方法的方式: # 基类.方法名(实例, 实际调用参数) A.works(b) # 用类名显示调用, A.works被调用
super 函数:
super(cls, obj)返回绑定超类的实例(要求obj必须是cls类的实例)
super() 返回绑定超类的实例, 等同于:super(__class__),
实例方法的第一个参数), 必须在方法内调用
作用:
借助于super()返回实例间接调用其父类的覆盖方法
# 用super函数返回的对象调用父类的覆盖方法 class A: def works(self): print("A.works被调用") class B(A): '''B继承A类''' def works(self): print("B.works被调用") def super_works(self): self.works() # B.works被调用 super(B, self).works() # A.works被调用 super().works() # A.works被调用 b = B() b.works() # B.works被调用 super(B, b).works() # A.works被调用 b = B() b.super_works() # B.works被调用
显示调用基类的初始化方法:
当子类中实现了__init__方法,基类的构造方法不会被调用
def __init__(self, ...)
# 用super函数调用父类的覆盖__init__初始化方法 class Human: def __init__(self, n, a): self. name, self.age = n, a print("Human类的 __init__ 方法被调用") def infos(self): print("name:", self.name) print("age:", self.age) class Student(Human): def __init__(self, n, a, s=0): super().__init__(n, a) # 用siper 调用父类的__init__方法 self.score = s # 添加成绩属性 print("Student类的 __init__ 方法被调用") def info(self): super().infos() # 调用父类的方法 print("name:", self.name) print("age:", self.age) print("score:", self.score) # 不调用父类的方法也不会出错 但是尽量不要用 s1 = Student("小张", 20) s1.infos()