Python--面向对象编程
2017-01-04 22:19 ZN23&24 阅读(89) 评论(0) 收藏 举报python基础-面向对象编程
一、三大编程范式
编程范式即编程的方法论,标识一种编程风格
三大编程范式:
1.面向过程编程
2.函数式编程
3.面向对象编程
二、编程进化论
1.编程最开始就是无组织无结构,从简单控制流中按步写指令
2.从上述的指令中提取重复的代码块或逻辑,组织到一起(比方说,你定义了一个函数),便实现了代码重用,且代码由无结构走向了结构化,创建程序的过程变得更具逻辑性
3.我们定义函数都是独立于函数外定义变量,然后作为参数传递给函数,这意味着:数据与动作是分离的
4.如果我们把数据和动作内嵌到一个结构(函数或类)里面,那么我们就有了一个‘对象系统’(对象就是数据与函数整合到一起的产物)。
1 假设你是一条狗,我们用结构化的数据来描述你 2 1:数据与动作分离 3 2:数据与动作结合 4 5 导向: 6 1.面向对象设计 7 2.什么是类什么是对象
三、面向对象设计与面向对象编程
def定义函数是面向对象
class定义类是面向对象
1、面向对象设计
面向对象设计(Object oriented design):将一类具体事物的数据和动作整合到一起,即面向对象设计
示例1:
1 #相当于:类
2 def dog(name,gender,type):
3 #狗的动作
4 def jiao(dog):
5 print('一条狗[%s],汪汪汪' % dog['name'])
6 def chi_shi(dog):
7 print('一条[%s] 正在吃肉' % dog['type'])
8 #狗的属性
9 def init(name,gender,type):
10 dog1 = {
11 'name':name,
12 'gender':gender,
13 'type':type,
14 'jiao':jiao, #动作
15 'chi_shi':chi_shi, #动作
16 }
17 return dog1
18 return init(name,gender,type)
19
20 d1=dog('元吴','母','中华犬')
21 d2=dog('alex','母','藏敖')
22 print(d1)
23 print(d2)
24 d1['jiao'](d1)
25 d2['chi_shi'](d2)
什么是类?
类:把一类事物的相同的特征和动作整合到一起就是类,类是一个抽象的概念。
什么是对象?
对象:就是基于类而创建的一个具体的事物(指具体存在的),也是特征和动作整合到一起。
示例2:
学校类:
特征:name,addr,type
动作:考试,招生,开除学生
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 def school(name,addr,type):
6 def init(name, addr, type):
7 sch = {
8 'name': name,
9 'addr': addr,
10 'type': type,
11 'kao_shi': kao_shi,
12 'zhao_sheng': zhao_sheng,
13 }
14 return sch
15 def kao_shi(school):
16 print('%s 学校正在考试' %school['name'])
17 def zhao_sheng(school):
18 print('%s %s 正在招生' %(school['type'],school['name']))
19 return init(name,addr,type)
20
21 s1=school('oldboy','沙河','私立学校')
22 print(s1)
23 print(s1['name'])
24
25 s1['zhao_sheng'](s1)
26
27 s2=school('清华','北京','公立学校')
28
29 print(s2)
30 print(s2['name'],s2['addr'],s2['type'])
31 s2['zhao_sheng'](s2)
2、面向对象编程
面向对象编程(object-oriented programming):用定义类+实例/对象的方式去实现面向对象的设计
1 #用面向对象编程独有的语法class去实现面向对象设计
2 class Dog:
3 def __init__(self,name,gender,type): #实例化的过程,就是运行__init__
4 self.name=name
5 self.gender=gender
6 self.type=type
7
8 def bark(self):
9 print('一条名字为[%s]的[%s],狂吠不止' %(self.name,self.type))
10
11 def yao_ren(self):
12 print('[%s]正在咬人' %(self.name))
13
14 def chi_shi(self):
15 print('[%s]正在吃屎' %(self.type))
16
17 dog1=Dog('alex','female','京巴')
18 dog2=Dog('wupeiqi','female','腊肠')
19 dog3=Dog('yuanhao','female','藏獒')
20
21 dog1.bark()
22 dog2.yao_ren()
23 dog3.chi_shi()
小结:
在Python中,类和 OOP 都不是日常编程所必需的。尽管它从一开始设计就是面向对象的,并且结构上支持 OOP,但 Python 没有限定或要求你在你的应用中写 OOP 的代码。
用面向对象语言写程序和一个程序的设计是面向对象的,两者就是两码事。
四、类和对象
1.什么叫类:类是一种数据结构,就好比一个模型,该模型用来表述一类事物(事物即数据和动作的结合体),用它来生产真实的物体(实例)。
2.什么叫对象:睁开眼,你看到的一切的事物都是一个个的对象,你可以把对象理解为一个具体的事物(事物即数据和动作的结合体)
(铅笔是对象,人是对象,房子是对象,狗是对象,alex是对象,配齐是对象,元昊是对象)
3.类与对象的关系:对象都是由类产生的,上帝造人,上帝首先有一个造人的模板,这个模板即人的类,然后上帝根据类的定义来生产一个个的人
4.什么叫实例化:由类生产对象的过程叫实例化,类实例化的结果就是一个对象,或者叫做一个实例(实例=对象)
五、类的相关知识
1、初识类
在python中声明函数与声明类很相似。
声明函数
|
1
2
3
|
1 def functionName(args):2 '函数文档字符串'3 函数体 |
声明类
1 ''' 2 class 类名: 3 '类的文档字符串' 4 类体 5 ''' 6 7 #我们创建一个类 8 class Data: 9 pass 10 11 #用类Data实例化出一个对象d1 12 d1=Data()
经典类与新式类
1 大前提: 2 1.只有在python2中才分新式类和经典类,python3中统一都是新式类 3 2.新式类和经典类声明的最大不同在于,所有新式类必须继承至少一个父类 4 3.所有类甭管是否显式声明父类,都有一个默认继承object父类(讲继承时会讲,先记住) 5 在python2中的区分 6 经典类: 7 class 类名: 8 pass 9 10 经典类: 11 class 类名(父类): 12 pass 13 14 在python3中,上述两种定义方式全都是新式类
示例:
1 #经典类(python2.7) 2 class Chinese: 3 '这是一个中国人的类' 4 pass 5 6 print(Chinese) 7 8 #新式类(python3.0) 9 10 #实例化到底干了什么? 11 p1=Chinese() #实例化 12 print(p1)
2、属性
类是用来描述一类事物,类的对象指的是这一类事物中的一个个体
是事物就要有属性,属性分为
1:数据属性:就是变量
2:函数属性:就是函数,在面向对象里通常称为方法
注意:类和对象均用点来访问自己的属性
类的属性
理论:数据属性即变量,类的定义与函数又极其类似,其实可以用函数的作用域来理解类的属性调用。
类的数据属性
1 #定义一个中文人的类,然后在类中定义一个类的属性,政府是共产堂,这样,只要是中文人他们的党永远都是共产堂 2 #类属性又称为静态变量,或者是静态数据。这些数据是与它们所属的类对象绑定的,不依赖于任何类实例。 3 #如果你是一位Java或C++程序员,这种类型的数据相当于在一个变量声明前加上static关键字。 4 5 class Chinese: 6 government='共产堂' 7 8 print(Chinese.government)
类的函数属性(又称为方法)
1 class Chinese:
2 government='***'
3 def sui_di_tu_tan():
4 print('90%的中国人都喜欢随地吐痰')
5
6 def cha_dui(self):
7 print('一个中国人-->%s<--插到了前面' %self)
8
9 Chinese.sui_di_tu_tan()
10
11 person1_obj='alex'
12 Chinese.cha_dui(person1_obj) #带参函数,所以调用时需要传入参数,将'alex'传给self
查看类属性
我们定义的类的属性到底存到哪里了?有两种方式查看
dir(类名):查出的是一个名字列表
类名.__dict__:查出的是一个字典,key为属性名,value为属性值
1 #共有属性,动作(方法)
2 class Chinese:
3 '这是一个中国人的类'
4 dang='共产堂' #数据属性
5 def sui_di_tu_tan(): #函数属性
6 print('朝着墙上就是一口痰')
7 def cha_dui(self): #加了self的就必须传一个参数,否则会报错
8 print('插到了前面')
9
10 print(Chinese.dang)
11 Chinese.sui_di_tu_tan()
12 Chinese.cha_dui('元昊')
13
14 # print(dir(Chinese)) #查看系统内置属性
15 # print(Chinese.__dict__) #查看属性字典
16 print(Chinese.__dict__['dang']) #调用数据属性,本身就是在数据属性中找东西
17 Chinese.__dict__['sui_di_tu_tan']() #调用函数属性,有了函数的内存地址,加(),就可以运行
18 Chinese.__dict__['cha_dui'](1) #调用函数属性
执行结果:
1 共产堂 2 在地上就是一口痰 3 插到了前面 4 共产堂 5 在地上就是一口痰 6 插到了前面
特殊的类属性
1 class Chinese:
2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物'
3 government='共产堂'
4 def sui_di_tu_tan():
5 print('90%的中国人都喜欢随地吐痰')
6
7 def cha_dui(self):
8 print('一个中国人-->%s<--插到了前面' %self)
9
10 print(Chinese.__name__) #类C的名字(字符串)
11 print(Chinese.__doc__) #类C的文档字符串
12 print(Chinese.__base__) #类C的第一个父类(在讲继承时会讲)
13 print(Chinese.__bases__) #类C的所有父类构成的元组(在讲继承时会讲)
14 print(Chinese.__dict__) #类C的属性
15 print(Chinese.__module__)#类C定义所在的模块
16 print(Chinese.__class__) #实例C对应的类(仅新式类中)
六、对象相关知识
对象是由类实例化而来,类实例化的结果称为一个实例或者称作一个对象
1.1、实例化
什么是实例化?
由类生产对象的过程就叫实例化
1 class Chinese:
2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物'
3 government='***'
4 def sui_di_tu_tan():
5 print('90%的中国人都喜欢随地吐痰')
6
7 def cha_dui(self):
8 print('一个中国人-->%s<--插到了前面' %self)
9
10 person1=Chinese() #类名加上括号就是实例化(可以理解为函数的运行,返回值就是一个实例)
11
12 #这就是实例化,只不过你得到的person1实例,没有做任何事情
1.2、构造函数
类是数据属性和函数属性的结合,描述的是一类事物
这类事物的一个具体表现就是一个实例/对象,比方说中国人是一个类,而你就是这个类的一个实例
你除了有中国人这个数据属性外,还应该有名字,年龄,性别等数据属性
如何为实例定制数据属性,可以使用类的一个内置方法__init__()该方法,在类()实例化是会自动执行
1 class Chinese:
2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物'
3 government='***'
4 def __init__(self,name,age,gender): #实例化的过程可以简单理解为执行该函数的过程,实例本身会当作参数传递给self(这是默认的步骤)
5 self.name=name
6 self.age=age
7 self.gender=gender
8
9 def sui_di_tu_tan():
10 print('90%的中国人都喜欢随地吐痰')
11
12 def cha_dui(self):
13 print('一个中国人-->%s<--插到了前面' %self)
14
15 # person1=Chinese() #会报错
16 #自动执行__init__方法,而这个方法需要参数,
17 # 这些参数应该写在类名后面的括号里,然后由类传
18 #给__init__函数,也就说,传给类的参数就是传给__init__的参数
19
20 person1=Chinese('alex',1000,'female')
21 person2=Chinese('wupeiqi',10000,'female')
22 person3=Chinese('yuanhao',9000,'female')
23
24 print(person1.__dict__)
注意:在说实例化的时候说过,执行类()会自动返回一值,这个值就是实例,而类()会自动执行__init__,所以一定不要在该函数内定义返回值,会冲突。
1.3、实例属性
理论:
1.实例只有数据属性(实例的函数属性严格来说是类的函数属性)
2.del 实例/对象,只是回收了实例的数据属性,函数属性是属于类的,是不会回收。
实例化的过程实际就是执行__init__的过程,这个函数内部只是为实例本身即self设定了一堆数据(变量),所以实例只有数据属性。
1 class Chinese:
2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物'
3 government='***'
4 def __init__(self,name,age,gender):
5 self.name=name
6 self.age=age
7 self.gender=gender
8
9 def sui_di_tu_tan():
10 print('90%的中国人都喜欢随地吐痰')
11
12 def cha_dui(self):
13 print('一个中国人-->%s<--插到了前面' %self)
14
15
16 person1=Chinese('alex',1000,'female')
17 print(person1.__dict__) #查看实例的属性,发现里面确实只有数据属性
18 print(person1.name,person1.age,person1.gender) #访问实例的数据属性
那么我们想访问实例的函数属性(其实是类的函数属性),如何实现
1 class Chinese:
2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物'
3 government='***'
4 def __init__(self,name,age,gender):
5 self.name=name
6 self.age=age
7 self.gender=gender
8
9 def sui_di_tu_tan():
10 print('90%的中国人都喜欢随地吐痰')
11
12 def cha_dui(self):
13 print('一个中国人-->%s<--插到了前面' %self)
14
15
16 person1=Chinese('alex',1000,'female')
17 print(person1.__dict__) #查看实例的属性,发现里面确实只有数据属性
18 print(Chinese.__dict__)#函数属性只存在于类中
19 Chinese.cha_dui(person1)#我们只能通过类去调用类的函数属性,然后把实例当做变量传递给self
改进版本
1 class Chinese:
2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物'
3 government='***'
4 def __init__(self,name,age,gender):
5 self.name=name
6 self.age=age
7 self.gender=gender
8
9 def sui_di_tu_tan():
10 print('90%的中国人都喜欢随地吐痰')
11
12 # def cha_dui(self):
13 # print('一个中国人-->%s<--插到了前面' %self)
14
15 def cha_dui(self):
16 print('一个中国人-->姓名:%s 年龄:%s 性别:%s<--插到了前面' %(self.name,self.age,self.gender))
17
18 def eat_food(self,food):
19 print('%s 正在吃 %s' %(self.name,food))
20
21 person1=Chinese('alex',1000,'female')
22 print(person1.__dict__) #查看实例的属性,发现里面确实只有数据属性
23 print(Chinese.__dict__)#函数属性只存在于类中
24 Chinese.cha_dui(person1)#我们只能通过类去调用类的函数属性,然后把实例当做变量传递给self
25 Chinese.eat_food(person1,'韭菜馅饼')
26
27
28 person1.cha_dui()#其实就是Chinese.cha_dui(person1)
29 person1.eat_food('飞禽走兽') #本质就是Chinese.eat_food(person1,'飞禽走兽')
3、实例属性和查看实例属性的方法如下:
同样是dir和内置__dict__两种方式

原理图
示例:
1 class Chinese:
2 '这是一个中国人的类'
3
4 dang='共产堂'
5
6 def __init__(self,name,age,gender):
7 print('我是初始化函数,我开始运行了')
8 self.mingz=name #name,age,gender都封装在self里面
9 self.nianji=age #p1.nianji=age
10 self.xingbin=gender #p1.xingbin=gender
11 print('我结束啦')
12
13 def sui_di_tu_tan():
14 print('在地上就是一口痰')
15 def cha_dui(self):
16 print(self)
17 print('%s 插到了前面' %self)
18 #return None (系统默认就是return None,这里不要加return)
19
20 #数据属性
21 p1=Chinese('元昊','18','female') #实例化的过程,就是调用__init__
22 print(p1.__dict__) #查看字典属性 #==>{'nianji': '18', 'mingz': '元昊', 'xingbin': 'female'}
23 print(p1.mingz) #p1.nianji=age, 直接调用__init__里面的属性,
24 print(p1.dang) #类的作用域概念,如果__init__里面没有,就去外面那层找,外层找到Class Chinese类字典
25
26 #实例属性没有函数属性,函数属性属于类
27 print(Chinese.__dict__)
28 Chinese.sui_di_tu_tan()
29 Chinese.cha_dui(p1)
30
31 #p1.sui_di_tu_tan() #class把p1作为参数自动加到sui_di_tu_tan(p1)括号里面,所以会报错。因为是python底层自动加上的。
32 p1.cha_dui() #p1里面没有,但是类里面有,所以能找到
执行结果:
1 我是初始化函数,我开始运行了
2 我结束啦
3 {'mingz': '元昊', 'xingbin': 'female', 'nianji': '18'}
4 元昊
5 共产堂
6 {'__init__': <function Chinese.__init__ at 0x0121F0C0>, '__doc__': '这是一个中国人的类', '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, 'sui_di_tu_tan': <function Chinese.sui_di_tu_tan at 0x0121F270>, 'dang': '共产堂', 'cha_dui': <function Chinese.cha_dui at 0x0121F228>, '__dict__': <attribute '__dict__' of 'Chinese' objects>}
7 在地上就是一口痰
8 <__main__.Chinese object at 0x01681210>
9 <__main__.Chinese object at 0x01681210> 插到了前面
10 <__main__.Chinese object at 0x01681210>
11 <__main__.Chinese object at 0x01681210> 插到了前面
12 China
13 Japan
14 {'name': 'alex'}
15 {'__init__': <function Chinese.__init__ at 0x0121F108>, 'dang': '共产堂', '__module__': '__main__', 'play_ball': <function Chinese.play_ball at 0x0121F198>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, 'country': 'Japan', '__doc__': None, '__dict__': <attribute '__dict__' of 'Chinese' objects>}
16 共产堂
17 {'__init__': <function Chinese.__init__ at 0x0121F108>, '__module__': '__main__', 'play_ball': <function Chinese.play_ball at 0x0121F198>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__doc__': None, '__dict__': <attribute '__dict__' of 'Chinese' objects>}
18 {'__init__': <function Chinese.__init__ at 0x0121F108>, '__module__': '__main__', 'play_ball': <function Chinese.play_ball at 0x0121F198>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__doc__': None, 'eat': <function eat_food at 0x011F2F60>, '__dict__': <attribute '__dict__' of 'Chinese' objects>}
19 alex 正在吃虾
20 test
1.4、特殊实例属性
__class__
__dict__
1 class Chinese:
2 '我们都是中国人,我们骄傲的活着,我们不服任何事和物'
3 government='***'
4 def __init__(self,name,age,gender):
5 self.name=name
6 self.age=age
7 self.gender=gender
8
9 def sui_di_tu_tan():
10 print('90%的中国人都喜欢随地吐痰')
11
12 # def cha_dui(self):
13 # print('一个中国人-->%s<--插到了前面' %self)
14
15 def cha_dui(self):
16 print('一个中国人-->姓名:%s 年龄:%s 性别:%s<--插到了前面' %(self.name,self.age,self.gender))
17
18 def eat_food(self,food):
19 print('%s 正在吃 %s' %(self.name,food))
20
21 person1=Chinese('alex',1000,'female')
22
23 print(person1.__class__)
24 print(Chinese)
25
26 person2=person1.__class__('xiaobai',900,'male')
27 print(person2.name,person2.age,person2.gender)
警告:类和对象虽然调用__dict__返回的是一个字典结构,但是千万不要直接修改该字典,会导致你的oop不稳定。
1.5、类属性与对象(实例)属性
1、类属性的增、删、改、查
1 class Chinese:
2 country='China'
3 def __init__(self,name):
4 self.name=name
5
6 def play_ball(self,ball):
7 print('%s 正在打 %s' %(self.name))
8
9 #查看
10 print(Chinese.country)
11
12 #修改
13 Chinese.country='Japan'
14 print(Chinese.country)
15
16 p1=Chinese('alex')
17 print(p1.__dict__) #从类的字典里面去找,上面已经修改过了,所以是Japan
18
19 #增加
20 Chinese.dang='共产堂'
21
22 #printChinese.dang)
23 #print(p1.dang)
24
25 #删除
26 del Chinese.dang
27 del Chinese.country
28
29 print(Chinese.__dict__)
30 #print(Chinese.country)
31
32
33 #给类增加一个函数属性
34 def eat_food(self,food): #定义了一个函数,
35 print('%s 正在吃%s' %(self.name,food))
36
37 Chinese.eat=eat_food
38
39 print(Chinese.__dict__)
40 p1.eat('虾') #给函数属性传参数
41
42
43 #增加
44 def test(self):
45 print('test')
46
47 Chinese.play_ball=test
48 p1.play_ball() #Chinese.play_ball(p1)
执行结果:
1 China
2
3 Japan
4
5 {'name': 'alex'}
6
7 {'play_ball': <function Chinese.play_ball at 0x01558108>, '__init__': <function Chinese.__init__ at 0x01085660>, '__doc__': None, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'Chinese' objects>}
8
9 {'play_ball': <function Chinese.play_ball at 0x01558108>, '__init__': <function Chinese.__init__ at 0x01085660>, '__doc__': None, 'eat': <function eat_food at 0x01532F60>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'Chinese' objects>}
10
11 alex 正在吃虾
12
13 test
2、实例属性的增、删、改、查
1 class Chinese:
2 country='China'
3 def __init__(self,name):
4 self.name=name
5
6 def play_ball(self,ball):
7 print('%s 正在打 %s' %(self.name,ball))
8 p1=Chinese('alex')
9 print(p1.__dict__)
10
11 #查看
12 # print(p1.name)
13 # print(p1.play_ball)
14
15 #增加
16 p1.age=18
17 print(p1.__dict__)
18 print(p1.age)
19
20 #不要修改底层的属性字典
21 # p1.__dict__['sex']='male'
22 # print(p1.__dict__)
23 # print(p1.sex)
24
25 #修改
26 p1.age=19
27 print(p1.__dict__)
28 print(p1.age)
29
30 #删除
31 del p1.age
32 print(p1.__dict__)
执行结果:
1 {'name': 'alex'}
2
3 {'age': 18, 'name': 'alex'}
4 18
5
6 {'age': 19, 'name': 'alex'}
7 19
8
9 {'name': 'alex'}
1.其实你会发现,实例化就是 类名(),然后返回的结果是一个对象,加上括号是不是跟函数运行很像,函数运行完了有返回值,是不是很像,没错,就是一样的。
2.函数又作用域的概念,其实类也有作用域的概念,二者一样
3.你可以把class当做最外层的函数,是一个作用域
1 #定义一个类,只当一个作用域去用,类似于c语言中的结构体 2 class MyData: 3 pass 4 5 x=10 6 y=20 7 MyData.x=1 8 MyData.y=2 9 10 print(x,y) 11 print(MyData.x,MyData.y) 12 print(MyData.x+MyData.y)
4.实例化会自动触发init函数的运行,最后返回一个值即实例,我们要找的实例属性就存放在init函数的局部作用域里
5.类有类的属性字典,就是类的作用域,实例有实例的属性字典,即实例的作用域
6.综上,一个点代表一层作用域,obj.x先从自己的作用域找,自己找不到去外层的类的字典中找,都找不到,就会报错
7.在类中没有使用点的调用,代表调用全局变量。
上面知识应用:
示例1:
1 class Chinese:
2 country='China'
3 def __init__(self,name):
4 self.name=name
5
6 def play_ball(self,ball):
7 print('%s 正在打 %s' %(self.name,ball))
8
9 p1=Chinese('alex')
10 print(p1.country) #访问的是类的
11 p1.country='日本' #把country改成日本
12 print('类的--->',Chinese.country) #类的---> China
13 print('实例的',p1.country) #在类的字典里,新增了一个p1.country='日本'。所以发果是:实例的 日本
示例2:
1 country='中国'
2 class Chinese:
3 def __init__(self,name):
4 self.name=name
5
6 def play_ball(self,ball):
7 print('%s 正在打 %s' %(self.name,ball))
8
9 p1=Chinese('alex')
10 # print(p1.country) #p1.country就是在类里面找,找不到就报错。
示例3:
1 country='中国'
2 class Chinese:
3 def __init__(self,name):
4 self.name=name
5
6 def play_ball(self,ball):
7 print('%s 正在打 %s' %(self.name,ball))
8
9 #另外定义一个函数,接收输入
10 def shi_li_hua():
11 name=input('>>: ')
12 p1=Chinese(name)
13 # print(p1.country)
14 print(p1.name)
15 shi_li_hua()
示例4:
1 country='中华人民共和国'
2 class Chinese:
3 country='中国'
4
5 def __init__(self,name):
6 self.name=name
7 print('--->',country) #即不是类的属性,也不是实例的属性。所以他就是变量的直接赋值
8
9 def play_ball(self,ball):
10 print('%s 正在打 %s' %(self.name,ball))
11
12 p1=Chinese('alex') #打印出来的值是变量, ---> 中华人民共和国
示例5:
1 country='中国' #从外面去找
2 class Chinese:
3 country='中国'
4 def __init__(self,name):
5 self.name=name
6 print('--->',country) #即不是类的属性,也不是实例的属性。所以他就是变量
7
8 def play_ball(self,ball):
9 print('%s 正在打 %s' %(self.name,ball))
10
11 #调用实例数据属性的两种方法如下:
12
13 #用.的方式调用:
14 print(Chinese.__dict__)
15 print(Chinese.country)
16
17 结果:
18 ---> 中国
19
20 #通过实例调用
21 p1=Chinese('alex')
22 print('实例--------》',p1.country)
23
24 结果:
25 实例--------》 中国
总结:
.的方式调用的是属性,要么跟类有关,要么跟实例有关
不加.就跟类没关,跟实例没关。
示例1:
1 class Chinese:
2 country='China'
3 def __init__(self,name):
4 self.name=name
5
6 def play_ball(self,ball):
7 print('%s 正在打 %s' %(self.name,ball))
8 p1=Chinese('alex')
9
10 print(p1.country) #打印的就是country本身
11 p1.country='Japan' #增加了一个实例,类本身不会更改
12 print(Chinese.country)
示例2:
1 class Chinese:
2 country='China'
3 l=['a','b']
4 def __init__(self,name):
5 self.name=name
6
7 def play_ball(self,ball):
8 print('%s 正在打 %s' %(self.name,ball))
9
10 p1=Chinese('alex')
11 print(p1.l) #p1本身自己没有,找的就是类,所以打印出来的值就是:['a', 'b']
12
13 p1.l=[1,2,3]
14 print(Chinese.l) #l 的值不会变,因为他是在1里面加入了一个新的字典。结果:['a', 'b']
15 print(p1.__dict__) #因为他是在1里面加入了一个新的字典。结果:{'l': [1, 2, 3], 'name': 'alex'}
示例3:
1 class Chinese:
2 country='China'
3 l=['a','b']
4 def __init__(self,name):
5 self.name=name
6
7 def play_ball(self,ball):
8 print('%s 正在打 %s' %(self.name,ball))
9
10 p1=Chinese('alex')
11 print(p1.l) #p1本身自己没有,找的就是类,所以打印出来的值就是:['a', 'b']
12
13 p1.l.append('c') #这不是在赋值和给实例新增属性。执行结果:['a', 'b']
14 print(p1.__dict__) #执行结果:{'name': 'alex'}
15 print(Chinese.l) #改的就是类里面的东西,所以直接增加进去了。执行结果:['a', 'b', 'c']
理论 :类的作用域即函数作用域
七、静态属性、类方法、静态方法
1、静态属性
作用就是:封装逻辑,把函数属性封装成数据属性
1 class Room:
2 def __init__(self,name,owner,width,length,heigh):
3 self.name=name
4 self.owner=owner
5 self.width=width
6 self.length=length
7 self.heigh=heigh
8
9 @property #静态属性
10 def cal_area(self): #计算面积
11 return self.width * self.length
12
13 @property
14 def cal_volume(self): #计算体积
15 return self.width * self.length * self.heigh
16
17 r1=Room('厕所','alex',1000,100,100000)
18 r2=Room('公共厕所','yuanhao',1,1,1)
19 r3=Room('主人房','nulige',10,10,10)
20
21 print(r1.cal_area)
22 print(r2.cal_area)
23 print(r3.cal_volume)
24 print(r1.name)
25 print(r2.name)
26 print(r3.name)
执行结果:
1 100000 2 1 3 1000 4 厕所 5 公共厕所 6 主人房
2、类方法
类方法作用:专门给类使用与实例无关,类方法只能访问类相关属性,不能访问实例属性(跟实例没有任何关系)
1 class Room: 2 tag=1 3 def __init__(self, name, owner, width, length, heigh): 4 self.name = name 5 self.owner = owner 6 self.width = width 7 self.length = length 8 self.heigh = heigh 9 10 @property 11 def cal_area(self): 12 return self.width * self.length 13 14 @classmethod #classmethod类方法只是给类使用(不管是否存在实例),只能访问实例变量
15 def tell_info(cls,x): 16 print(cls) 17 print('---->',cls.tag) 18 19 Room.tell_info(1)
执行结果:
1 <class '__main__.Room'> 2 ----> 1
3、静态方法
1 ''' 2 staticmethod静态方法只是名义上的归属类管理,不能使用类变量和实例变量,是类的工具包 3 ''' 4 5 class Room: 6 def __init__(self,name,owner,width,length): 7 self.name=name 8 self.owner=owner 9 self.width=width 10 self.length=length 11 12 @property 13 def cal_area(self): 14 return self.width * self.length 15 16 @staticmethod #类的工具包,不跟类绑定,也不跟实例绑定(无法调用实例的东西)
17 def wash_body(): 18 print('洗刷刷,洗刷刷') 19 20 def test(): 21 print('这可不是静态方法,用类调用没问题,你用一个实例调用看看') 22 23 Room.wash_body() 24 25 r1=Room('厕所','alex',10,10) 26 r1.wash_body() 27 28 29 30 #------ 31 Room.test() 32 r1.test() #会报错,因为如果test不是静态方法,那么r1会吧自己传给test的第一个参数self,test无参所以报错 33 34 静态方法
八、组合
一、组合的组成部分
定义一个人的类,人有头,驱赶,手,脚等数据属性,这几个属性又可以是通过一个类实例化的对象,这就是组合
简单理解:就是大类包含小类,就是组合。
用途:
1:做关联
2:小的组成大的
1 class Hand:
2 pass
3
4 class Foot:
5 pass
6
7 class Trunk:
8 pass
9
10 class Head:
11 pass
12
13 class Person:
14 def __init__(self,id_num,name):
15 self.id_num=id_num #身份证号码
16 self.name=name
17 self.hand=Hand()
18 self.foot=Foot()
19 self.trunk=Trunk()
20 self.head=Head()
21
22 p1=Person('111111','alex') #给实例传值
23 print(p1.__dict__) #查看实例的属性字典
执行结果:
1 {'foot': <__main__.Foot object at 0x011B4130>, 'trunk': <__main__.Trunk object at 0x011B4170>, 'id_num': '111111', 'hand': <__main__.Hand object at 0x011B40D0>, 'name': 'alex', 'head': <__main__.Head object at 0x011B4190>}
二、选课系统
示例1:
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 #选课系统
6
7 #一种很LOW的关联方法:
8 class School:
9 def __init__(self,name,addr):
10 self.name=name
11 self.addr=addr
12 self.course_list=[]
13
14 def zhao_sheng(self):
15 print('%s 正在招生' %self.name)
16
17 class Course:
18 def __init__(self,name,price,period):
19 self.name=name
20 self.price=price
21 self.period=period
22
23 s1=School('oldboy','北京')
24 s2=School('oldboy','上海')
25 s3=School('oldboy','天津')
26
27 c1=Course('linux',5800,'1h')
28 c2=Course('python',9800,'1h')
29
30 s1.course_list.append(c1)
31 s1.course_list.append(c2)
32 print(s1.__dict__) #打印字典属性
33
34 for course_obj in s1.course_list:
35 print(course_obj.name,course_obj.price)
执行结果:
1 {'course_list': [<__main__.Course object at 0x01984190>, <__main__.Course object at 0x019841B0>], 'name': 'oldboy', 'addr': '北京'}
2
3 linux 5800
4 python 9800
示例2:
用组合的方式实现
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 class School:
6 def __init__(self,name,addr):
7 self.name=name
8 self.addr=addr
9
10 #招生
11 def zhao_sheng(self):
12 print('%s 正在招生' %self.name)
13
14 class Course:
15 def __init__(self,name,price,period,school):
16 self.name=name
17 self.price=price
18 self.period=period
19 self.school=school
20
21 s1=School('oldboy','北京')
22 s2=School('oldboy','上海')
23 s3=School('oldboy','天津')
24
25 # c1=Course('linux',5800,'1h','oldboy北京')
26 # c1=Course('python',9800,'1h',s1 )
27
28 msg='''
29 1 老男孩 北京校区
30 2 老男孩 上海校区
31 3 老男孩 天津校区
32 '''
33 while True:
34 print(msg)
35 menu={
36 '1':s1,
37 '2':s2,
38 '3':s3,
39 }
40
41 choice=input('请选择学校:')
42 school_obj=menu[choice]
43 name=input('课程名: ')
44 price=input('课程费用: ')
45 period=input('课程周期: ')
46 new_course=Course(name,price,period,school_obj)
47 print('课程[%s] 属于[%s] 学校' %(new_course.name,new_course.school.name))
执行结果:
1 1 老男孩 北京校区 2 2 老男孩 上海校区 3 3 老男孩 天津校区 4 5 请选择学校:1 6 课程名: python 7 课程费用: 9800 8 课程周期: 1h 9 课程[python] 属于[oldboy] 学校 10 11 1 老男孩 北京校区 12 2 老男孩 上海校区 13 3 老男孩 天津校区 14 15 请选择学校:

浙公网安备 33010602011771号