面向对象函数式编程
#狗的特征
dog1 =
{'name' : '冀祥'
'gender' : '母'
'type' : '柯基'}
dog2 =
{'name' : '刘鹏'
'gender' : '母'
'type' : '法斗'}
dog3 =
{'name' : '姚宇轩'
'gender' : '公'
'type' : '泰迪'}
def dog(name,gender,type): #这是一个类
def jiao(dog): #这是类的函数属性
print('有一条狗[%s]在汪汪汪' % dog['name'])
def chi_shi(dog): #这是类的函数属性
print('有一条[%s]在吃屎' % dog['type'])
def init(name,gender,type): #此步骤为初始化函数,值为传来的参数,key为新的参数,防止有默认值
d1 = {'name' : name,
'gender' : gender,
'type' : type,
'jiao' : jiao,
'chi_shi' : chi_shi}
return d1
return init(name,gender,type) #直接返回实例的信息
dog1 = dog('冀祥','母','柯基') #实例化
dog1['jiao'](dog1) #用实例调用类的方法,用实例本身当作参数传入
dog1['chi_shi'](dog1)
def school(name,addr,type):
def init(name,addr,type):
sch = {
'name' : name,
'addr' : addr,
'type' : type,
'examination' : examination,
'recruit_students' : recruit_students
}
return sch
def examination(school):
print('%s 学校正在考试' %school['name'])
def recruit_students(school):
print('%s学校 %s 正在招生' %(school['type'],school['name']))
return init(name,addr,type)
s1 = school('剑桥','England','私立')
print(s1)
print(s1['name'])
s1['recruit_students'](s1)
s2 = school('哈佛','America','公立')
print(s2['name'])
s2['examination'](s2)
面向对象独有语法class
class Dog: #正规格式为首字字母大写
def __init__(self,name,gender,type): #self为默认参数,实则代表实例名
self.name = name #dog1.xingming = name
self.gender = gender #dog1.xingbie = gender
self.type = type #dog1.leixing = type
def bark(self):
print('一条叫[%s]的[%s]不停地叫唤' %(self.name,self.type))
def bite(self):
print('[%s]又咬人了' %(self.name))
def chi_shi(self):
print('一条[%s]正在吃屎' %(self.type))
dog1 = Dog('冀祥','female','柯基')
print(dog1.__dict__) #以字典形式
dog2 = Dog('刘鹏','male','藏獒')
dog3 = Dog('宇轩','male','京巴')
# dog1.bark()
# dog2.bite()
dog3.chi_shi() #用.的方式调用本质上就是在自己的属性字典中中寻找函数属性,相当于:
Dog.__dict__['chi_shi'](dog3)
# print(Dog.__dict__['bite'](dog1))
print(Dog.__name__)
print(Dog.__doc__)
print(Dog.__module__) #__main__,代表文件名
类属性增删改查
class Chinese:
country = 'China' #新建一个实例,即数据属性
def __init__(self,name):
self.name = name
def play_games(self,ball):
print('%s 正在打%s' %(self.name))
#查看
print(Chinese.country)
#修改
Chinese.country = 'America'
print(Chinese.country) #America
p1 = Chinese('harvey')
print(p1.__dict__) #{'name': 'harvey'}
print(p1.country) #America
#增加
Chinese.addr = 'Asian'
print(Chinese.addr)#Asian
print(p1.addr)#Asian
#删除
del Chinese.addr
del Chinese.country
print(Chinese.country) #报错
def have_breakfast(self,food):
print('%s 正在吃 %s' %(self.name,food))
Chinese.food = have_breakfast #将一个函数添加到Chinese类中成为他的函数属性
print(Chinese.__dict__) #此时已经在Chinese的字典属性中
p1.food('提拉米苏')
def test(self):
print('我在玩泥巴')
Chinese.play_games = test #覆盖之前的play_games
p1.play_games() #p1.Chinese.play_games(p1) 默认传入p1到self位置
实例属性增删改查
class Chinese:
country = 'China' #新建一个实例,即数据属性
def __init__(self,name):
self.name = name
def play_games(self,ball):
print('%s 正在打%s' %(self.name))
p1 = Chinese('harvey')
print(Chinese.__dict__)
#查看
print(p1.name)
print(p1.play_games)
#增加
p1.age = 18 #增加数据属性
print(p1.__dict__) #{'name': 'harvey', 'age': '18'}
print(p1.age)
#删除
del p1.age
print(p1.age) #报错
#修改
#不要修改底层的属性字典
#p1.__dict__['gender'] = 'female'
p1.age = 19
print(p1.age) #19
class Chinese:
country='China'
l=['a','b']
def __init__(self,name):
self.name=name
def play_ball(self,ball):
print('%s 正在打 %s' %(self.name,ball))
p1=Chinese('alex')
print(p1.l) #['a', 'b']
p1.l=[1,2,3]
print(Chinese.l) #['a', 'b']
print(p1.__dict__) #{'name': 'alex', 'l': [1, 2, 3]}
p1.l.append('c') #用实例调用来l,添加字符串'c',但并不会改变类的l
print(p1.__dict__) #{'name': 'alex', 'l': [1, 2, 3, 'c']},实例的字典属性中添加成功
print(Chinese.l) #['a', 'b']但类中不改变
封装
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
# def area(self):
# print('%s住的%s面积是%s' %(self.owner,self.name,self.width*self.length))
#r1 = Room('海景房','harvey',100,80,10)
#r1.area() #r1.area 封装后不需要括号
@property #封装
def area(self):
return self.width*self.length
r1 = Room('海景房','harvey',100,80,10)
print(r1.area) #加了返回值可以实现用户或别人这样使用你的程序,封装逻辑
print(r1.name) #使你的程序更有神秘感,无法被看破,调用形式都相同
#那如果我们不想通过实例,直接访问类的详情信息呢?
def test(self):
# print('这是test函数',self.name)
# print(Room.tag)
# Room.test() #报错,因为类调用类自己的函数属性必须通过实例
# Room.test(1) #1.name,随便传一个参数也报错
@classmethod #类可以直接调用,不需要实例了。用于解决类调用自己的方法而不借助实例
def tell_info(cls): #cls相当于接收了一个类名
print(cls) #<class '__main__.Room'>
print(cls.tag)
#Room.tell_info() #1,可以直接调用类的方法了
#工具包,既不跟实例捆绑,也不跟类捆绑,完全脱离的方法,只为类提供服务
@staticmethod
def take_shawer(a,b,c):
print('%s %s %s正在一起洗澡' %(a,b,c))
Room.take_shawer('我','你','她')
组合
class School:
def __init__(self,name,addr):
self.name = name
self.addr = addr
def recruit(self):
print('%s 正在招生' %self.name)
class Course:
def __init__(self,name,price,school):
self.name = name
self.price = price
self.school = school
s1 = School('剑桥','England')
s2 = School('剑桥','America')
# c1 = Course('English','30k','剑桥','England')#报错,位置参数过多
c1 =Course('English','30k',s1)
print(c1.school.name)
print(s2.name)
print(c1.name)
s2.recruit()
class School:
def __init__(self,name,addr):
self.name = name
self.addr = addr
def recruit(self):
print('%s 正在招生' %self.name)
class Course:
def __init__(self,name,price,school):
self.name = name
self.price = price
self.school = school
s1 = School('剑桥','England')
s2 = School('剑桥','America')
s3 = School('剑桥','Australia')
msg = '1 剑桥 Endland,2 剑桥 America,3 剑桥 Australia'
while True:
print(msg)
menu = {
'1':s1,
'2':s2,
'3':s3
}
choice = input('选择学校:')
school_obj = menu[choice]
name = input('选择课程:')
price = input('课程费用:')
new_course = Course(name,price,school_obj)
print('课程[%s]属于[%s],费用是[%s]' %(new_course.name,new_course.school.name,new_course.price) )
继承
class Dad:
money = 10
def __init__(self,name):
print('这是爸爸')
self.name = name
def teach(self):
print('%s正在教育他儿子%s' %self.name)
class Son(Dad):
money = 999999
def __init__(self,name,age):
self.name = name
self.age = age
def teach(self):
print('来自子类')
print(Son.money) #999999
Son.teach(2) #来自子类
s1 = Son('harvey',18)
s1.teach() #来自子类
print(s1.money) #999999
print(s1.name) #harvey
print(Dad.money) #10
子类调用父类的方法
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):
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 tell_info(self):
print(self.name,self.speed,self.load,self.power,self.line)
def run(self):
super().run() #Vehicle.run(self)也可以,但不实用。这是父类的run
print('(儿子)%s %s 出发啦' %(self.name,self.line)) #这是子类的run
四号线 = Subway('北京地铁','10km/s','10万','电力','4')
四号线.run()
四号线.tell_info()
#接口继承
import abc
class All_file(metaclass=abc.ABCMeta):
@abc.abstractmethod
def read(self):
print('All_file read')
@abc.abstractmethod
def write(self):
print('All_file write')
class Disk():
def read(self):
print('Disk read')
def write(self):
print('Disk write')
class Cdrom():
def read(self):
print('Cdrom read')
def write(self):
print('Cdrom write')
class Men():
def read(self):
print('Men read')
def write(self): #若此类没有写入方法,在没有abc模块的约束下,程序也能运行
print('Men write')#abc模块帮我们规范各类的方法,此类必须要跟上类有共同方法,不然在实例化时会报错
m1 = Men()
m1.read()
m1.write()