目录
一:类 & 对象
类的定义(两种)
class Student(object):
class Student:
构造函数写法: __init__
对象的创建:stu1 = Student()
class Student(object): # 类的另外一种写法 class Student:
def __init__(self): # 构造函数写法 init
pass
stu1 = Student() # 创建对象
print(stu1, type(stu1))
输出结果:
<__main__.Student object at 0x00000225025A8708> <class '__main__.Student'>
二:公有 & 私有
1 公有的成员变量 类外部可以访问
class Student(object): # 类
def __init__(self): # 构造函数
# 成员变量 公有
self.sno = 1001 # 成员变量 学号
self.name = "lily" # 成员变量 姓名
stu1 = Student() # 创建对象
print(stu1.sno)
print(stu1.name)
输出结果:
1001
lily
2 私有的成员变量 类外部无法访问
私有 写法: self.__
self.__pwd = "123456" # 私有成员变量
print(stu1.__pwd) # 私有 类外部无法访问
三:构造函数 & 成员函数
1 带参构造
def __init__(self, sno, name, pwd):
class Student(object): # 类
def __init__(self, sno, name, pwd): # 带参构造
self.sno = sno # 公有成员变量
self.name = name # 公有成员变量
self.__pwd = pwd # 私有成员变量
stu1 = Student(1001, "lily", "123456") # 创建对象
print(stu1.name)
stu2 = Student(1002, "sam", "654321") # 创建对象
print(stu2.name)
输出结果:
lily
sam
2 类的成员函数(可以访问类的成员变量)
写法:def say_hello(self, age): # 类的成员函数 self可以访问类的成员变量
调用:stu1.say_hello(20) # self表示当前对象 不需要传参
class Student(object): # 类
def __init__(self, sno, name, pwd): #带参构造
self.sno = sno # 公有成员变量
self.name = name # 公有成员变量
self.__pwd = pwd # 私有成员变量
def say_hello(self, age): # 类的成员函数 self可以访问类的成员变量
print("大家好,我是", self.name, "我今年", age, "岁")
stu1 = Student(1001, "lily", "123456") # 创建对象
stu1.say_hello(20) # self表示当前对象 不需要传参
输出结果:
大家好,我是 lily 我今年 20 岁
3 析构函数
写法 def __del__(self):
创建了几个对象就会执行几次析构
class Student(object): # 类
def __init__(self, sno, name, pwd): # 带参构造
self.sno = sno # 公有成员变量
self.name = name # 公有成员变量
self.__pwd = pwd # 私有成员变量
def say_hello(self, age): # 类的成员函数 self可以访问类的成员变量
print("大家好,我是", self.name, "我今年", age, "岁")
def __del__(self):
print("执行析构函数")
stu1 = Student(1001, "lily", "123456") # 创建对象
stu2 = Student(1002, "sam", "654321") # 创建对象
输出结果:创建2次对象,执行2次析构
执行析构函数
执行析构函数
四:静态成员函数 & 静态成员变量
普通方法、类方法、静态方法 三者区别:
普通方法:由对象调用,至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self
类方法:由类调用;至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls
静态方法:由类调用;无默认参数
1 静态成员函数,使用staticmethod修饰符修饰
示例如下(静态函数 没有对象也可调用,可以直接通过类名访问,静态函数归类所有)
写法: @staticmethod # 静态函数
def static_fun():
print("静态函数")调用:Student.static_fun() # 静态函数 可以直接类访问
class Student(object): # 类
def __init__(self, sno, name, pwd): # 带参构造
self.sno = sno # 公有成员变量
self.name = name # 公有成员变量
self.__pwd = pwd # 私有成员变量
def say_hello(self, age): # 类的成员函数 self可以访问类的成员变量
print("大家好,我是", self.name, "我今年", age, "岁")
@staticmethod # 静态函数
def static_fun():
print("静态函数")
def __del__(self):
print("执行析构函数")
Student.static_fun() # 静态函数 可以直接类访问
输出结果:静态可以直接 类访问
静态函数
2 静态成员变量(类成员)
定义: count = 0 # 静态成员 类成员
访问: Student.count += 1 # 静态成员 可直接类访问
静态函数可以访问静态成员变量:
@staticmethod # 静态函数
def static_fun():
print("静态函数,count = ", Student.count) # 静态函数可以访问静态成员
class Student(object): # 类
count = 0 # 静态成员 类成员
def __init__(self, sno, name, pwd): # 带参
self.sno = sno # 公有成员变量
self.name = name # 公有成员变量
self.__pwd = pwd # 私有成员变量
Student.count += 1 # 静态成员 可直接类访问
def say_hello(self, age): # 类的成员函数 self可以访问类的成员变量
print("大家好,我是", self.name, "我今年", age, "岁")
@staticmethod # 静态函数
def static_fun():
print("静态函数,count = ", Student.count) # 静态函数可以访问静态成员
def __del__(self):
pass
stu1 = Student(1001, "lily", "123456") # 创建对象
stu2 = Student(1002, "sam", "654321") # 创建对象
Student.static_fun() # 静态函数可以访问静态成员
输出结果: 创建2次对象调用2次带参构造
静态函数,count = 2
五:类方法
1 类成员函数(类方法)
a.先定义一个类成员: class_name = "OMO2203" # 类成员
b.classmethod修饰符修饰类成员函数:
@classmethod # 类成员函数
def class_fun(cls):
print(cls.class_name)c.类方法,可以直接 类访问
Student.class_fun() # 类方法 可以直接类访问
class Student(object): # 类
class_name = "OMO2203" # 类成员
def __init__(self, sno, name, pwd): # 带参
self.sno = sno # 公有成员变量
self.name = name # 公有成员变量
self.__pwd = pwd # 私有成员变量
def say_hello(self, age): # 类的成员函数 self可以访问类的成员变量
print("大家好,我是", self.name, "我今年", age, "岁")
@classmethod # 类成员函数
def class_fun(cls):
print(cls.class_name)
def __del__(self):
pass
Student.class_fun() # 类方法 可以直接类访问
输出结果:
OMO2203
注意点:
类成员函数 可以访问类成员 不能访问普通成员变量 ,
如下示例
sno为普通成员变量,类成员函数不能访问
@classmethod # 类成员函数
def class_fun(cls):
print(cls.class_name, cls.sno)
六:单继承
单继承 示例
示例1
a.走父类构造
b.子类属性可直接赋值,父类属性可继承后赋值
c.走析构
class AnimalClass: # 动物类
def __init__(self, name, id): # 带参构造
self.name = name # 公有成员变量
self.id = id # 公有成员变量
self.__private = 'animal' # 私有成员变量
print("走父类构造")
def eat(self, food): # 吃
print("eat", food)
def drink(self, water): # 喝
print("drink", water)
def la(self): # 拉
print("bianbian")
def sa(self): # 撒
print("...")
class CatClass(AnimalClass): # 子类(猫)继承父类(动物类)
def __init__(self, name, id, type): # 带参构造
# 子类/父类方法名一致时:重写
AnimalClass.__init__(self, name, id) # 调用父类(AnimalClass)的构造方法
self.type = type # 公有成员变量
# 子类自己特有的方法
def speak(self): # 说话
print("miao miao")
def __del__(self): # 析构函数
print("析构")
mimi = CatClass('mimi', '1001', "波斯猫") # 子类 创建对象
print(mimi, "子类的属性:type = {},父类的属性:name = {}".format(mimi.type, mimi.name))
输出结果:
走父类构造
<__main__.CatClass object at 0x000001CA44B1AB88> 子类的属性:type = 波斯猫,父类的属性:name = mimi
析构
示例2
子类 调用子类方法
mimi = CatClass('mimi', '1001', "波斯猫") # 子类 创建对象
mimi.speak()
输出结果:
走父类构造
miao miao
析构
示例3
实例化对象
mimi是CatClass
mimi是AnimalClass
子类是子类/父类的对象
mimi = CatClass('mimi', '1001', "波斯猫") # 子类 创建对象
print("mimi是否是CatClass的对象", isinstance(mimi, CatClass))
print("mimi是否是AnimalClass的对象", isinstance(mimi, AnimalClass))
输出结果:
走父类构造
mimi是否是CatClass的对象 True
mimi是否是AnimalClass的对象 True
析构
示例4
子类可以调用父类的方法(公有继承)
mimi = CatClass('mimi', '1001', "波斯猫") # 子类 创建对象
mimi.drink('water') # 子类调用父类方法
输出结果:
走父类构造
drink water
析构
示例5
子类可以访问父类的普通成员变量(公有继承)
mimi = CatClass('mimi', '1001', "波斯猫") # 子类 创建对象
print("小猫的名字:%s" % mimi.name)
输出结果:
走父类构造
小猫的名字:mimi
析构
示例6
再举例 之 单继承(狗继承动物类)
class DogClass(AnimalClass): # 子类(狗)继承父类(动物类)
def speak(self):
print("wang wang")
def __del__(self): # 析构函数
print("析构")
dog = DogClass("wangcai", "2002")
print("小狗的名字:%s" % dog.name)
输出结果:
走父类构造
小狗的名字:wangcai
析构
七:多继承
多继承 示例
示例1
歌手、舞者 继承 明星类 (多继承)
# 歌手 舞者 类
# 明星类 多继承
class Singer: # 歌手类
def __init__(self, name): # 带参
self.sing_name = name # 名字
@staticmethod
def sing(): # 唱
print("唱歌")
@staticmethod
def lyricist(): # 作词
print("会作词")
@staticmethod
def compose(): # 作曲
print("作曲")
class Dancer: # 舞者类
def __init__(self, type): # 带参
self.type = type # 从业类型
@staticmethod
def dance(): # 跳舞
print("跳舞")
@staticmethod
def uben(): # 编舞
print("编舞")
class StarClass(Singer, Dancer): # 歌手、舞者多继承 明星类
def __init__(self, name, compony, nick_name, type): # 带参
Singer.__init__(self, name) # 歌手带参
Dancer.__init__(self, type) # 舞者带参
self.name = name # 名字
self.compony = compony # 公司
self.nick_name = nick_name # 艺名
@staticmethod
def sing(): # 重写父类方法 假唱
print("假唱")
star = StarClass("chenyi", "xx传媒", "Angle", "广场舞") # 创建对象
print(star.name) # 名字
print(star.compony) # 公司
print(star.nick_name) # 艺名
print(star.type) # 从业类型
输出结果:
chenyi
xx传媒
Angle
广场舞
示例2
python3版本中存在有:单继承 可使用super超类的方法
执行顺序为 先父后子:父构造 子构造 父方法 子方法 父析构 子析构
class FooParent(object): # 父类
def __init__(self):
self.parent = 'I\'m the parent .'
print('Parent')
def bar(self, message):
print("%s from Parent" % message)
def __del__(self):
print("Parent del")
class FooChild(FooParent): # 子类继承父类
def __init__(self):
super().__init__() # 单继承 super
print('child')
# 重定义父类的方法
def bar(self, message):
# super调用父类的方法
super(FooChild, self).bar(message)
print('Child bar function')
def __del__(self):
# super调用父类的方法 需要.__del__()
super(FooChild, self).__del__()
print("Child del")
if __name__ == '__main__':
fooChild = FooChild() # 初始化子类
fooChild.bar('HelloWorld')
输出结果:先父后子
Parent
child
HelloWorld from Parent
Child bar function
Parent del
Child del
示例3 省份 共用确定值设置静态(中国China)
prop 属性 的使用
class Province(object): # 省份
# 共有的确定值 静态字段
country = 'China'
def __init__(self, name, city_name, num):
# 普通字段
self.name = name # 名字
self.c_city = city_name # 省会
self.num = num # 邮政编码
# 所有对象所拥有的方法
@classmethod
def printInfo(cls): # 类方法
print("省所属国家:", cls.country)
@staticmethod
def staticMethod(arg): # 静态
print("静态方法")
print(arg)
@property
def prop(self): # 属性
print('属性')
@prop.setter
def prop(self, value):
# 成绩 分数值 --- 等级段 95 A
# 属性的条件限制
print("属性设置:", value)
self.num = value
@prop.deleter
def prop(self):
del self.num
jiangxi = Province('江西', '南昌', '330000') # 创建对象
# jiangxi.prop 普通方法的变种 对象.属性方法名称 ps:没有形参列表
jiangxi.prop = 'aaa' # 属性
# a.属性设置
jiangxi.num = 'bbb' # 破坏类的结构
print(jiangxi.num)
# b.属性删除
del jiangxi.prop
# print('删除后:',jiangxi.num)
# 类调用静态方法
Province.staticMethod('people')
# 类调用调用类方法
Province.printInfo()
输出结果:
属性设置:属性设置: aaa
bbb静态方法:静态方法
people类方法: 省所属国家: China
八:多态
多态,简单示例
def who_am_i(x)
print x.whoAmI()
p = Person('Tim','Male')
s = Student('Bob','Male',88)
t = Teacher('Alice','Female','English')
#不同的类 调用同一个函数 (多态)
who_am_i(p)
who_am_i(s)
who_am_i(t)
输出结果:
I am a Person,my name is Tim
I am a Student,my name is Bob
I am a Teacher,my name is Alice
小结:
这种行为称为多态
也就是说,方法调用将作用在x的实际类型上
s是Student类型,它实际上拥有自己的whoAmI方法以及Person继承的whoAmI方法,
但是 调用s.whoAmI()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止
九:模块、包
直接运行当前脚本
模块名称:__main__ (确定运行哪个模块)
if __name__ == '__main__':
# 直接运行当前脚本 模块名称:__main__
s = Student(1001, "lily", "123456") # 创建对象
写法格式1:
import 模块名称
如下 import cv2 # 模块所在的路径已经添加到系统环境变量
import cv2 # 模块所在的路径已经添加到系统环境变量
写法格式2:
from 模块名称 import */类/函数 (模块名称python_base 是.py文件名)
from python_base import Student (Student 学生类)
from python_base import Student
stu = Student(1003, "kity", "123")
写法格式3:
from 包名.模块名称 import */类/函数 (模块名称python_base是.py文件名,class01是包名,该包存在有python_base.py脚本)
from class01.python_base import * (class01包名、python_base模块名)
对于上述格式,如在包class02中的某个文件(模块)下需要class01中某个文件(模块)的某个类,则可以使用该格式写法
一个包里面可以有多个脚本.py(模块)
# import 模块名称
# from 模块名称 import */类/函数
# from 包名.模块名称 import */类/函数
from class01.python_base import *
Student(1001, "xiaoming", "999999")