一、面向对象设计
面向对象设计(Object oriented design):将一类事物的数据和动作整合到一起,即面向对象设计
def school(name,addr,type): def init(name, addr, type): sch = { 'name': name, 'addr': addr, 'type': type, 'test': test, 'recruit': recruit, } return sch def test(school): print('%s 学校正在考试' %school['name']) def recruit(school): print('%s %s 正在招生' %(school['type'],school['name'])) return init(name,addr,type) s1=school('清华大学','北京','公立学校') print(s1) #{'recruit': <function school.<locals>.recruit at 0x000001BB3023E400>, 'test': <function school.<locals>.test at 0x000001BB3023E378>, 'name': '清华大学', 'type': '公立学校', 'addr': '北京'} print(s1['name']) #清华大学 s1['recruit'](s1) #公立学校 清华大学 正在招生 s2=school('北大','北京','公立学校') print(s2) print(s2['name'],s2['addr'],s2['type']) #北大 北京 公立学校 s2['recruit'](s2) #公立学校 北大 正在招生
二、面向对象编程
用面向对象编程独有的语法class去实现面向对象设计
class Dog: def __init__(self,name,gender,type): self.name=name self.gender=gender self.type=type def bark(self): print('一条名字为[%s]的[%s],狂吠不止' %(self.name,self.type)) def eat(self): print('[%s]正在吃骨头' %(self.name)) def sleep(self): print('[%s]正在睡觉' %(self.type)) dog1=Dog('小黑','female','京巴') print(dog1.__dict__) #{'name': '小黑', 'type': '京巴', 'gender': 'female'} dog1.bark() dog1.eat() dog1.sleep()
三、类
对象是具体的存在,而类仅仅只是一个概念,并不真实存在,在程序中,务必保证先定义类,后产生对象
类:把一类事物的相同的特征和动作整合到一起就是类,类是一个抽象的概念
对象:基于类二创建的一个具体的事物(具体存在的),也是特征和动作整合到一起
实例化:有类生产对象的过程叫实例化,类实例化的结果就是一个对象(实例=对象)
3.1、类的声明
''' class ClassName: '类的文档注释' 类体 ''' #创建有一个类 class Data: pass #实例化 d1=Data()
3.2、经典类和新式类
#经典类 class 类名: pass #新式类 class 类名(父类): pass #注意:在python2中存在经典类和新式类,但在python3中只有新式类
3.3、类的属性
类的属性分为:
- 数据属性:变量
- 函数属性:函数,在面向对象中称为方法
- 类和对象均用点来访问自己的属性
class Dog: '这是一个狗的类' feature='哺乳动物' def eat(): print('吃骨头') def sleep(self): print('sleeping') # print(Dog.feature) #哺乳动物 Dog.eat() #吃骨头 Dog.sleep("小黑") #sleeping print(dir(Dog)) #打印key值 #['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'eat', 'feature', 'sleep'] print(Dog.__dict__) #查看属性字典,打印键值对 #{'eat': <function Dog.eat at 0x00000183C602E158>, '__dict__': <attribute '__dict__' of 'Dog' objects>, 'sleep': <function Dog.sleep at 0x00000183C602E378>, '__module__': '__main__', 'feature': '哺乳动物', '__weakref__': <attribute '__weakref__' of 'Dog' objects>, '__doc__': '这是一个狗的类'} print(Dog.__dict__['feature']) #哺乳动物 Dog.__dict__['eat']() #吃骨头 Dog.__dict__['sleep'](1) #sleeping print(Dog.__name__) #Dog print(Dog.__doc__) #这是一个狗的类 print(Dog.__module__) #__main__
查看类的属性有两种方法:
- dir(类名):查出来的是一个名字列表
- 类名.__dict__:查出来的是一个字典,key为属性名,value是属性值
特殊的属性:
print(Dog.__name__) #Dog ==>类的名字(字符串) print(Dog.__doc__) #这是一个狗的类 ==>文档字符串 print(Dog.__module__) #__main__ ==>类定义所在的模块 print(Dog.__base__) #<class 'object'> ==>类的第一个父类 print(Dog.__bases__) #(<class 'object'>,) ==>类的所有类构成的元祖 print(Dog.__dict__) #{'__doc__': '这是一个狗的类', 'sleep': <function Dog.sleep at 0x000001CC7319E378>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__weakref__': <attribute '__weakref__' of 'Dog' objects>, 'eat': <function Dog.eat at 0x000001CC7319E158>, '__module__': '__main__', 'feature': '哺乳动物'} print(Dog.__class__) #<class 'type'> ==>实例对应的类(仅新式类)
3.4、类属性的增删改查
class Chinese: country='China' def __init__(self,name): self.name=name def play_ball(self,ball): print('%s 正在打 %s' %(self.name)) #查看 print(Chinese.country) #China #修改 Chinese.country='AAA' print(Chinese.country) #AAA p1=Chinese('abc') print(p1.__dict__) #{'name': 'abc'} print(p1.country) #AAA #增加 Chinese.location = "Asia" print(Chinese.location) #Asia print(p1.location) #Asia #删除 del Chinese.location del Chinese.country print(Chinese.__dict__) # print(Chinese.country) #AttributeError: type object 'Chinese' has no attribute 'country' def eat(self,food): print('%s 正在吃%s' %(self.name,food)) #增加函数方法 Chinese.eat=eat print(Chinese.__dict__) p1.eat('美食') #abc 正在吃美食 def test(self): print('test') Chinese.play_ball=test p1.play_ball() #test ==>相当于 Chinese.play_ball(p1)
四、实例
对象是由类实例化来的。类实例化的结果称之为一个实例或一个对象
4.1、实例化
class Dog: '这是一个狗的类' feature='哺乳动物' def eat(self): print('吃骨头') def sleep(self): print('sleeping') dog1 = Dog() #类名() ==>实例化 print(dog1) #<__main__.Dog object at 0x00000227ABEC5C50>
4.2、构造方法
使用类的内置方法__init__方法,在类()实例化时会自动执行,为实例定制数据属性
class Dog: feature='哺乳动物' def __init__(self,name,age,gender): #实例化可以简单理解为执行该函数的过程,实例本身会当做参数传给self self.name = name self.age = age self.gender = gender def eat(self): print('吃骨头') def sleep(self): print('sleeping') dog1 = Dog("黑",10,"female") #==>相当于Dog.__init__(self,name,age,gender) print(dog1) #<__main__.Dog object at 0x0000019EC86043C8> print(dog1.__dict__) #{'name': '黑', 'age': 10, 'gender': 'female'} ==>只有数据属性 print(Dog.__dict__) #函数属性只存在类中 #{'__weakref__': <attribute '__weakref__' of 'Dog' objects>, 'feature': '哺乳动物', '__init__': <function Dog.__init__ at 0x000001DA9FA3E378>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__module__': '__main__', '__doc__': None, 'sleep': <function Dog.sleep at 0x000001DA9FA3E488>, 'eat': <function Dog.eat at 0x000001DA9FA3E400>} print(dog1.age) #10 # print(dog1.eat(dog1)) #TypeError: eat() takes 1 positional argument but 2 were given #只能通过类取调用类的函数属性,然后把实例当做变量传给self Dog.eat(dog1) #吃骨头
4.3、查看实例属性
print(dir(dog1)) print(dog1.__dict__) #{'name': '黑', 'age': 10, 'gender': 'female'} ==>只有数据属性
4.4、特殊实例属性
类和对象虽然调用__dict__返回的是一个字典结构,但是不要直接修改字典,会导致oop不稳定
dog1 = Dog("黑",10,"female") print(dog1.__class__) #<class '__main__.Dog'> print(dog1.__dict__) #{'gender': 'female', 'name': '黑', 'age': 10} print(dog1.__dict__["gender"]) #female
4.5、实例属性增删改查
class Chinese: country='China' def __init__(self,name): self.name=name def play_ball(self,ball): print('%s 正在打 %s' %(self.name,ball)) p1=Chinese('alex') print(p1.__dict__) #{'name': 'alex'} #查看 print(p1.name) #alex print(p1.play_ball) #<bound method Chinese.play_ball of <__main__.Chinese object at 0x00000246ADEE5C18>> #增加 p1.age=18 print(p1.__dict__) #{'age': 18, 'name': 'alex'} print(p1.age) #18 # #不要修改底层的属性字典 # p1.__dict__['sex']='male' # print(p1.__dict__) # print(p1.sex) # #修改 p1.age=19 print(p1.__dict__) #{'age': 19, 'name': 'alex'} print(p1.age) # #删除 del p1.age print(p1.__dict__) #{'name': 'alex'}
4.6、类与实例属性注意事项
#实例一 class Chinese: country='China' def __init__(self,name): self.name=name def play_ball(self,ball): print('%s 正在打 %s' %(self.name,ball)) p1=Chinese('AA') print(p1.country) #China p1.country='日本' print('类:',Chinese.country) #类: China print('实例:',p1.country) #实例: 日本 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++ #实例二 country='中国' class Chinese: def __init__(self,name): self.name=name def play_ball(self,ball): print('%s 正在打 %s' %(self.name,ball)) p1=Chinese('AAA') print(p1.country) #AttributeError: 'Chinese' object has no attribute 'country' #类中没有country属性 #++++++++++++++++++++++++++++++++++++++++++++++++++++++ #实例三 country='大中国' class Chinese: # country='中国' #当类中没有时会报错 def __init__(self,name): self.name=name print('--->',country) def play_ball(self,ball): print('%s 正在打 %s' %(self.name,ball)) print(Chinese.__dict__) # print(Chinese.country) #AttributeError: type object 'Chinese' has no attribute 'country' p1=Chinese('alex') # print('实例--------》',p1.country) #AttributeError: 'Chinese' object has no attribute 'country' #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #实例四 class Chinese: country='China' def __init__(self,name): self.name=name def play_ball(self,ball): print('%s 正在打 %s' %(self.name,ball)) p1=Chinese('alex') print(p1.country) #China p1.country='Japan' #修改的是实例的属性 print(Chinese.country) #China #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #实例五 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) # print(p1.__dict__) p1.l.append('c') #通过append方式修改的是类的属性 print(p1.__dict__) #{'name': 'alex'} print(Chinese.l) #['a', 'b', 'c']