# 一、静态
# 在Python中,"静态"通常指静态方法或静态属性。以下是关于静态方法和静态属性的介绍:
# 静态方法(@staticmethod)
# 静态方法是属于类而不是类实例的方法。它们不需要实例化对象就可以被调用。静态方法使用 @staticmethod 装饰器来定义。
class Room:
tag=1
def __init__(self,name,owner,width,length,heigh):
self.name=name
self.owner=owner
self.width=width
self.length=length
self.heigh=heigh
@property
def cal_area(self):
# print('%s 住的 %s 总面积是%s' % (self.owner,self.name, self.width * self.length))
return self.width * self.length
@classmethod
def tell_info(cls,x):
print(cls)
print('--》',cls.tag,x)#print('--》',Room.tag)
# def tell_info(self):
# print('---->',self.tag)
@staticmethod
def wash_body(a,b,c):
print('%s %s %s正在洗澡' %(a,b,c))
def test(x,y):
print(x,y)
# Room.wash_body('alex','zhangfei','zhaoyun')
print(Room.__dict__)
r1=Room('厕所','alex',100,100,100000)
print(r1.__dict__)
# r1.wash_body('alex','zhangfei','zhaoyun')
# Room.test(1,2)
# r1.test(1,2)
# 静态属性
# Python中没有直接的“静态属性”这个概念,但是可以通过类变量实现类似功能。类变量是类对象的变量,而不是实例变量,这意味着它们可以被类的所有实例共享。
# 示例:
class Room:
tag=1
def __init__(self,name,owner,width,length,heigh):
self.name=name
self.owner=owner
self.width=width
self.length=length
self.heigh=heigh
@property
def cal_area(self):
# print('%s 住的 %s 总面积是%s' % (self.owner,self.name, self.width * self.length))
return self.width * self.length
def test(self):
print('from test',self.name)
@classmethod
def tell_info(cls,x):
print(cls)
print('--》',cls.tag,x)#print('--》',Room.tag)
# def tell_info(self):
# print('---->',self.tag)
# print(Room.tag)
# Room.test(1) #1.name
# r1=Room('厕所','alex',100,100,100000)
Room.tell_info(10)
# r1=Room('厕所','alex',100,100,100000)
# r2=Room('公共厕所','yuanhao',1,1,1)
# # print('%s 住的 %s 总面积是%s' %(r1.owner,r1.name,r1.width*r1.length))
# # print('%s 住的 %s 总面积是%s' %(r2.owner,r2.name,r2.width*r2.length))
# # r1.cal_area()
# # r2.cal_area()
# print(r1.cal_area)
# print(r2.cal_area)
# print(r1.name)
# print(r2.name)
#类的方法:
class Room:
tag=1
def __init__(self,name,owner,width,length,heigh):
self.name=name
self.owner=owner
self.width=width
self.length=length
self.heigh=heigh
@property
def cal_area(self):
# print('%s 住的 %s 总面积是%s' % (self.owner,self.name, self.width * self.length))
return self.width * self.length
def test(self):
print('from test',self.name)
@classmethod
def tell_info(cls,x):
print(cls)
print('--》',cls.tag,x)#print('--》',Room.tag)
# def tell_info(self):
# print('---->',self.tag)
# print(Room.tag)
# Room.test(1) #1.name
# r1=Room('厕所','alex',100,100,100000)
Room.tell_info(10)
# 二、组合
# 在Python中,组合(Composition)是一种设计模式,它通过将一个类的实例作为另一个类的属性来实现。组合通常用于表示“has-a”关系,即一个类包含另一个类的实例,而不是通过继承来实现“is-a”关系。
# 组合的优势在于它提供了更大的灵活性和可维护性,因为它避免了多重继承带来的复杂性。
# class Hand:
# pass
#
# class Foot:
# pass
#
# class Trunk:
# pass
#
# class Head:
# pass
#
#
# class Person:
# def __init__(self,id_num,name):
# self.id_num=id_num
# self.name=name
# self.hand=Hand()
# self.foot=Foot()
# self.trunk=Trunk()
# self.head=Head()
# p1=Person('111111','alex')
# print(p1.__dict__)
# class School:
# def __init__(self,name,addr):
# self.name=name
# self.addr=addr
#
# def zhao_sheng(self):
# print('%s 正在招生' %self.name)
#
# class Course:
# def __init__(self,name,price,period,school):
# self.name=name
# self.price=price
# self.period=period
# self.school=school
#
#
#
# s1=School('goodboy','北京')
# s2=School('goodboy','南京')
# s3=School('goodboy','东京')
#
# # c1=Course('linux',10,'1h','goodboy 北京')
# c1=Course('linux',10,'1h',s1)
#
# print(c1.__dict__)
# print(c1.school.name)
# print(s1)
class School:
def __init__(self,name,addr):
self.name=name
self.addr=addr
def zhao_sheng(self):
print('%s 正在招生' %self.name)
class Course:
def __init__(self,name,price,period,school):
self.name=name
self.price=price
self.period=period
self.school=school
s1=School('goodboy','北京')
s2=School('goodboy','南京')
s3=School('goodboy','东京')
# c1=Course('linux',10,'1h','goodboy 北京')
# c1=Course('linux',10,'1h',s1)
msg='''
1 好男孩 北京校区
2 好男孩 南京校区
3 好男孩 东京校区
'''
while True:
print(msg)
menu={
'1':s1,
'2':s2,
'3':s3
}
choice=input('选择学校>>: ')
school_obj=menu[choice]
name=input('课程名>>: ')
price=input('课程费用>>: ')
period=input('课程周期>>: ')
new_course=Course(name,price,period,school_obj)
print('课程【%s】属于【%s】学校' %(new_course.name,new_course.school.name))
# 三、继承
# 1.什么是类的继承?
# 类的继承跟现实生活中的父、子、孙子、重孙子、继承关系一样,父类又称为基类。
# python中类的继承分为:单维承和多继承
class ParentClass1:
pass
class ParentClass2:
pass
class SubClass1(ParentClass1): # 单继承
pass
class SubClass2(ParentClass1, ParentClass2): # 多继承
pass
# 解释:
# 单继承:在Python中,一个类可以继承自另一个类,从而继承其父类的属性和方法。这种继承方式称为单继承。在上面的代码中,SubClass1 继承自 ParentClass1,因此 SubClass1 是 ParentClass1 的子类,而 ParentClass1 是 SubClass1 的父类。
# 多继承:Python也支持一个类同时继承自多个父类,这种继承方式称为多继承。在上面的代码中,SubClass2 同时继承自 ParentClass1 和 ParentClass2。这意味着 SubClass2 将继承这两个父类的所有属性和方法(当然,如果两个父类中有同名的属性和方法,需要按照特定的规则进行解析,这里不展开讲解)。
class Dad:
'这个是爸爸类'
money=10
def __init__(self,name):
print('爸爸')
self.name=name
def hit_son(self):
print('%s 正在打儿子' %self.name)
class Son(Dad):
money = 1000000000009
def __init__(self,name,age):
self.name=name
self.age=age
def hit_son(self):
print('来自儿子类')
# print(Son.money)
# Son.hit_son()
# print(Dad.__dict__)
# print(Son.__dict__)
s1=Son('alex',18)
s1.hit_son()
# print(s1.money)
# print(Dad.money)
# print(s1.name)
# print(s1.money)
# print(s1.__dict__)
# s1.hit_son()
# 2、子继承到底继承了父类的什么属性?
# 子类继承了父类的所有属性,子类自定义的属性如果跟父类重名了,各用各的,子类那就用自己的,父类也用他自己的
# 3、什么时候用继承?
# 1.当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好
# 例如:描述一个机器人类,机器人这个大类是由很多互不相关的小类组成,如机械胳膊类、腿类、身体类、电池
# 类
# 2.当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好
# 例如
# 猫可以:喵喵叫、吃、喝、拉、撒
# 狗可以:汪汪叫、吃、喝、拉、撒
# 如果我们要分别为猫和狗创建一个类,那么就需要为猫 和狗实现他们所有的功能,如下所示:
class 猫:
def 喵喵叫(self):
print '喵喵叫'
def 吃(self):
# do something
def 喝(self):
# do something
def 拉(self):
# do something
def 撒(self):
# do something
class 狗:
def 汪汪叫(self):
print '喵喵叫'
def 吃(self):
# do something
def 喝(self):
# do something
def 拉(self):
# do something
def 撒(self):
# do something
# 上述代码不难看出,吃、喝、拉、撒是猫和狗都具有的功能,而我们却分别的猫和狗的类中编写了两次。如果使用 继承 的思想,如下实现:
# 动物:吃、喝、拉、撒
# 猫:喵喵叫(猫继承动物的功能)
# 狗:汪汪叫(狗继承动物的功能)
class 动物:
def 吃(self):
# do something
def 喝(self):
# do something
def 拉(self):
# do something
def 撒(self):
# do something
# 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
class 猫(动物):
def 喵喵叫(self):
print
'喵喵叫'
# 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
class 狗(动物):
def 汪汪叫(self):
print
'汪汪叫'
# 实例代码:
class Animal:
def eat(self):
print
"%s 吃 " % self.name
def drink(self):
print
"%s 喝 " % self.name
def shit(self):
print
"%s 拉 " % self.name
def pee(self):
print
"%s 撒 " % self.name
class Cat(Animal):
def __init__(self, name):
self.name = name
self.breed = '猫'
def cry(self):
print
'喵喵叫'
class Dog(Animal):
def __init__(self, name):
self.name = name
self.breed = '狗'
def cry(self):
print
'汪汪叫'
# ######### 执行 #########
c1 = Cat('小白家的小黑猫')
c1.eat()
c2 = Cat('小黑的小白猫')
c2.drink()
d1 = Dog('胖子家的小瘦狗')
d1.eat()
# 4 、继承同时具有两种含义
# 含义一,继承基类的方法,并且做出自己的改变或者扩展(代码重用)
# 含义二.声明某个子类兼容于某基类,定义一个接口类,子类继承接口类,并且实现接口中定义的方法
# 实践中,继承的第一种含义意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。
# 继承的第二种含义非常重要。它又叫“接口继承"。
# 接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细
# 节,可一视同仁的处理实现了特定接口的所有对象"一-这在程序设计上,叫做归一化。
# 归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合就好象linux的泛文件概念一样,
# 所有东西都可以当文件处理,不必关心它是内存、磁盘、网络还是屏幕(当然,对底层设计者,当然也可以区分
# 出“字符设备”和“块设备",然后做出针对性的设计:细致到什么程度,视需求而定).
# 接口继承
import abc
class All_file(metaclass=abc.ABCMeta):
@abc.abstractmethod
def read(self):
pass
@abc.abstractmethod
def write(self):
pass
class Disk(All_file):
def read(self):
print('disk read')
def write(self):
print('disk write')
class Cdrom(All_file):
def read(self):
print('cdrom read')
def write(self):
print('cdrom write')
class Mem(All_file):
def read(self):
print('mem read')
def write(self):
print('mem write')
#
m1=Mem()
m1.read()
m1.write()
# 5、继承顺序
# 是否可以继承多个类
# 如果继承的多个类每个类中都定了相同的函数,那么那一个会被使用呢?
# 1、Python的类可以继承多个类,Java和C#中则只能继承一个类
# 2、Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
#A
#B D F
#C E F
#coding:utf-8
class A:
# def test(self):
# print('A')
pass
class B(A):
# def test(self):
# print('B')
pass
class C(A):
# def test(self):
# print('C')
pass
class D(B):
# def test(self):
# print('D')
pass
class E(C):
# def test(self):
# print('E')
pass
class F(D,E):
# def test(self):
# print('F')
pass
f1=F()
f1.test() #经典类:F->D->B->A-->E-->
# print(F.__mro__)
#F-->D->B-->E--->C--->A新式类
# 终极解密:python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列
# 表,这个MRO列表就是一个简单的所有基类的线性顺序列表
# 为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
# 而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合
# 并所有父类的MRO列表并遵循如下三条准则:
# 1.子类会先于父类被检查
# 2.多个父类会根据它们在列表中的顺序被检查
# 3.如果对下一个类存在两个合法的选择,选择第一个父类
# 6、子类中调用父类方法
# 子类继承了父类的方法,然后想进行修改,
# 注意了是基于原有的基础上修改,那么就需要在子类中调用父类的方
# 法
# 方法一:指名道姓,即父类名.父类方法()
#_*_coding:utf-8_*_
__author__ = 'zhugeliang'
class Vehicle: #定义交通工具类
Country='China'
def __init__(self,name,speed,load,power):
self.name=name
self.speed=speed
self.load=load
self.power=power
def run(self):
print('开动啦...')
class Subway(Vehicle): #地铁
def __init__(self,name,speed,load,power,line):
Vehicle.__init__(self,name,speed,load,power)
self.line=line
def run(self):
print('地铁%s号线欢迎您' %self.line)
Vehicle.run(self)
line13=Subway('中国地铁','180m/s','1000人/箱','电',13)
line13.run()
# 在子类中调用父类的方法
class Vehicle:
Country='China'
def __init__(self,name,speed,load,power):
self.name=name
self.speed=speed
self.load=load
self.power=power
def run(self):
print('开动啦')
print('开动啦')
class Subway(Vehicle):
def __init__(self,name,speed,load,power,line):
Vehicle.__init__(self,name,speed,load,power)
self.line=line
def show_info(self):
print(self.name,self.speed,self.load,self.power,self.line)
def run(self):
Vehicle.run(self)
print('%s %s 线,开动啦' %(self.name,self.line))
line13=Subway('北京地铁','10km/s',1000000000,'电',13)
line13.show_info()
line13.run()
# super方法的使用
class Vehicle1:
Country='China'
def __init__(self,name,speed,load,power):
self.name=name
self.speed=speed
self.load=load
self.power=power
def run(self):
print('开动啦')
print('开动啦')
class Subway(Vehicle1):
def __init__(self,name,speed,load,power,line):
# Vehicle.__init__(self,name,speed,load,power)
# super().__init__(name,speed,load,power) #super(__class__,self).__init__(name,speed,load,power)
super(Subway,self).__init__(name,speed,load,power)
self.line=line
def show_info(self):
print(self.name,self.speed,self.load,self.power,self.line)
def run(self):
# Vehicle.run(self)
super().run()
print('%s %s 线,开动啦' %(self.name,self.line))
line13=Subway('北京地铁','10km/s',1000000000,'电',13)
line13.show_info()
line13.run()
print(line13.__class__)
# low比解决关联的方法
class School:
def __init__(self,name,addr):
self.name=name
self.addr=addr
self.course_list=[]
def zhao_sheng(self):
print('%s 正在招生' %self.name)
class Course:
def __init__(self,name,price,period):
self.name=name
self.price=price
self.period=period
s1=School('goodboy','北京')
s2=School('goodboy','南京')
s3=School('goodboy','东京')
c1=Course('linux',10,'1h')
c2=Course('python',10,'1h')
s1.course_list.append(c1)
s1.course_list.append(c2)
print(s1.__dict__)
for course_obj in s1.course_list:
print(course_obj.name,course_obj.price)
# 作业:
import pickle
import hashlib
import time
def create_md5():
m = hashlib.md5()
m.update(str(time.time()).encode('utf-8'))
return m.hexdigest()
id=create_md5()
time.sleep(1)
id1=create_md5()
time.sleep(1)
id2=create_md5()
print(id)
print(id1)
print(id2)
class Base:
def save(self):
with open('school.db','wb') as f:
pickle.dump(self,f)
class School(Base):
def __init__(self,name,addr):
self.id=create_md5()
self.name=name
self.addr=addr
class Course(Base):
def __init__(self,name,price,period,school):
self.id=create_md5()
self.name=name
self.price=price
self.period=period
self.school=school
school_obj = pickle.load(open('school.db', 'rb'))
print(school_obj.name,school_obj.addr)
# s1=School('goodboy','北京')
# s1.save()