类和对象的关系就像数据结构和数据的关系一样,类规定了存储什么数据,对象用来实际存储数据
"""
1.类的定义和构造
2.类的方法(函数) 构造 析构
一般函数的第一个参数是实例对象名,代之需要调用函数的对象,传参时不传入
3.类的属性(成员) 公有 私有
"""
"""
python 不存在无法访问的私有属性
如何保持封装的封闭性
"""
class student:
__age=0#私有成员
name=""#公有成员
Id=""
def __init__(self,name,age,Id):#构造函数
self.name=name
self.Id=Id
self.__age=age
print("%s同学的信息构造完成"%self.name)
def __del__(self):#析构函数
print("%s同学的信息被删除"%self.name)
def printf(self):#查看信息
print("%s同学的年龄为:%s\n学号为:%s"%(self.name,self.__age,self.Id))
if __name__ == '__main__':
#信息构造
stu1=student("李华","21","20212203")
stu2=student("李明","20","20212204")
stu3=student("李强","21","20212201")
#信息查看
stu1.printf()
stu2.printf()
stu3.printf()
#在类外调用私有成员要加类名限制(私有成员在类外也是可以定义的)
print("%s同学的年龄为:%s"%(stu1.name,stu1._student__age))
#信息删除
stu4=stu1
del stu1#对象信息备份在stu4
del stu2
del stu3
"""
这里的复数对象要当作字符串输出,定义__str__方法实现
"""
class complex:
def __init__(self,real,image):
self.real=real
self.image=image
def __str__(self):
if self.image >=0:
return str(self.real)+'+'+str(self.image)+'i'
else:
return str(self.real)+str(self.image)+'i'
'''
def __str__(self):
if self.image >= 0:
return '{}+{}i'.format(self.real,self.image)
else:
return '{}{}i'.format(self.real,self.image)
'''
c=complex(-1,2.3)
print(c)
c1=c=complex(1,-2.3)
print(c1)
"""
定义一个学生类,判断一个同学的成绩是否大于另一个
感觉有点类似于C++运算符重载
"""
class student:
def __init__(self,name,score):
self.score=score
self.name=name
def __gt__(self,other):
return self.score>=other.score
stu1=student('李华',78)
stu2=student('李明',80)
print('李明的成绩高于李华:',stu2.score>stu1.score)
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
在鸭子类型中,关注点在于对象的行为,能作什么;而不是关注对象所属的类型。
鸭子类型使得有相同功能的不同类也能实现多态,这是C++不具备的
"""
在鸭子类型中,关注点在于对象的行为,能作什么;
而不是关注对象所属的类型。
"""
class person:
def __init__(self,name,age):
self.name=name
self.age=age
def printt(self):
print('%s的年龄为%d'%(self.name,self.age))
class Dog:
def __init__(self,name,weight):
self.name=name
self.weight=weight
def printt(self):
print('狗狗%s的体重为%d'%(self.name,self.weight))
def printt(tmp):
tmp.printt()
c1=person('李华',12)
c2=Dog('乔治', 100)
printt(c1)
printt(c2)
1.单继承与多继承
2.方法重写: 方法重写就是在继承中子类对于父类已有的功能进行重写,可以通过鸭子类型实现多态
3.super: 获取当前类父类的代理对象(一般用于子类构造函数对父类元素赋值)
"""
1.单继承与多继承
2.方法重写: 方法重写就是在继承中子类对于父类已有的功能进行重写,可以通过父类的引用实现多态
3.super: 获取当前类父类的代理对象(一般用于子类构造函数对父类元素赋值)
学生
人——> ——> 助教
老师
"""
class person:
def __init__(self,sex,name):
self.sex=sex;
self.name=name
def Printinfo(self):
print('{}的性别为{}'.format(self.name,self.sex))
class student(person):
def __init__(self,sex,name,sno):
super().__init__(sex,name)
self.sno=sno
def Printinfo(self):
print('{}的性别为{},学号为{}'.format(self.name,self.sex,self.sno))
class teacher(person):
def __init__(self,sex,name,tno):
super().__init__(sex,name)
self.tno=tno
def Printinfo(self):
print('{}的性别为{},教师号为{}'.format(self.name,self.sex,self.tno))
class assistant(teacher,person):
pass
def Printinfo(tem):
tem.Printinfo()
c1=teacher('男', '李华', '11230')
c2=student('女', '李梅', '12345')
c3=person('男', '李强')
Printinfo(c1)
Printinfo(c2)
Printinfo(c3)
暂时不知python怎么消除多继承二义性,对于助教类先不扩展
1.isinstance 判断一个类是否是指定类或者是指定类的子类
2.issubclass 判断一个类是否是另一个类的子类
3.type()函数 获取一个对象所属的类
"""
1.isinstance 判断一个类是否是指定类或者是指定类的子类
2.issubclass 判断一个类是否是另一个类的子类
3.type()函数 获取一个对象所属的类
"""
class person:
def __init__(self,sex,name):
self.sex=sex;
self.name=name
class student(person):
def __init__(self,sex,name,sno):
super().__init__(sex,name)
self.sno=sno
class flower:
def __init__(self,colour):
self.colour=colour
c1=person('男','李明')
c2=student('女','李华','12345')
c3=flower('red')
print(type(c1))
print(type(c2))
print(type(c3))
print('flower类是person类的子类:',issubclass(flower,person))
print('flower类是person类的子类:',issubclass(student,person))
当一个属性是类所有而不是每个对象所拥有的时候要定义为类方法或静态方法,二者的区别是静态方法不用 写self,即静态方法并不绑定对象,也就无法修改对象的值
# -*- coding: utf-8 -*-
"""
类方法与静态方法:当类的一个方法是类所有而不是对象的方法时,可以定义为类方法或静态方法
类方法:@calssmethon 绑定了对象
静态方法:@staticmethod 未绑定对象
未绑定对象无法修改对象的值
"""
class complex:
def __init__(self,real=0,image=0):
self.real=real
self.image=image
@classmethod#类方法
def add1(cls,c1,c2):
c=complex()
c2.real=3
c.real=c1.real+c2.real
c.image=c1.image+c2.image
if c.image >=0:
return str(c.real)+'+'+str(c.image)+'i'
else:
return str(c.real)+str(c.image)+'i'
@staticmethod#静态方法
def add2(c1,c2):
c=complex()
#c2.real=1 在静态方法里修改对象的值无法修改成功
c.real=c1.real+c2.real
c.image=c1.image+c2.image
if c.image >=0:
return str(c.real)+'+'+str(c.image)+'i'
else:
return str(c.real)+str(c.image)+'i'
c1=complex(1,2)
c2=complex(2,3)
c3=complex.add1(c1,c2)
print(c3)
c4=complex.add1(c1,c2)
print(c4)
动态扩展类:在不修改原有类的情况下动态的为类添加新的属性或方法
1.绑定新方法:需要使用 types 模块的 MethodType 方法
from types import Mythodtype
2.绑定新属性:
可以使用__slots__函数限制可绑定的新属性
"""
动态扩展类:在不修改原有类的情况下动态的为类添加新的属性或方法
1.绑定新方法:需要使用 types 模块的 MethodType 方法
from types import Mythodtype
2.绑定新属性:
可以使用__slots__函数限制可绑定的新属性
"""
from types import MethodType
class person:
def __init__(self,sex,name):
self.sex=sex;
self.name=name
def printname(self):
print('%s'%self.name)
def printsex(self):
print('%s'%self.sex)
# 注意 __name__ 的用法
if __name__ == '__main__':
person.printname=printname
p1=person('男','李强')
p2=person('女','李华')
p1.printsex=MethodType(printsex,p1)
#给person类绑定printname方法,给对象p1绑定printsex
p1.printname()
p2.printname()
p1.printsex()
#p2.printsex() p2 无 printsex 这个功能
class person:
__slots__=('name')
class teacher(person):
__slots__=('tno')
class student(person):
pass
# 子类有限制会继承父类的限制,子类无限制不继承父类限制
if __name__ == '__main__':
p1=person()
p1.name='李华'
t1=teacher()
t1.name='李强'
t1.tno='123'
#t1.sno='122' t1 不允许扩展 sno 会报错
print('%s'%t1.tno)
s1=student()
s1.name='丽丽'
s1.tno='123'
s1.height='12'
print('%s'%s1.height)
# student类无限制,随意扩展
使用 __del__ 方法时 , 当要释放一个对象的内存时
会先检查一个对象的引用计数,只有 count = 0 时才会释放内存
"""
使用 __del__ 方法时 , 当要释放一个对象的内存时
会先检查一个对象的引用计数,只有 count = 0 时才会释放内存
我们可以通过 sys 模块中的 getrefcount 来获取一个对象的引用计数
导致引用计数+1的情况:
1.对象被创建
2.对象被引用
3.对象作为参数被传入到一个函数中
4.对象作为元素被存储在容器中
导致引用计数-1的情况:
1.对象的别名被显式销毁
2.对象的别名被赋给了新的对象
3.一个对象离开了它的作用域(如一个函数执行完后,它里面的局部变量)
4.对象所存在的容器被销毁,或从容器中删除了对象
"""
import sys
class people:
def __del__(self):
print("对象已被销毁")
pass
p1=people() #count = 1
count=sys.getrefcount(p1) # 对象作为参数被传到了一个函数中 count = 2
print(count)
p2=p1 #对象被引用 count = 3
count=sys.getrefcount(p1)
print(count)
del p2 #count = 1
print("-------1--------")
del p1 #count = 0
print("-------2--------")