Python——面向对象、绑定对象、组合
1. 面向过程VS面向对象
(1)面向过程
核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。
优点是:极大的降低了写程序的复杂度,只需要顺着要执行的步骤,堆叠代码即可。
缺点是:一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身。
应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。
(2)面向对象
核心是对象(上帝式思维),要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的属性和方法),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙互相缠斗着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取。
优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
缺点:可控性差,无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法预测最终结果。于是我们经常看到一个游戏人某一参数的修改极有可能导致阴霸的技能出现,一刀砍死3个人,这个游戏就失去平衡。
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方。
2. 相关名词概念
(1)类
类:具有相同特征的一类事物(人、狗、老虎)
(2)对象(实例)
对象/实例:具体的某一个事物(隔壁阿花、楼下旺财)
(3)实例化
实例化:类——>对象的过程(这在生活中表现的不明显,我们在后面再慢慢解释)
3. 类的相关知识
(1)类的定义
class Person: #定义一个类:Person
role = 'person' #人的角色属性都是人
def walk(self): #人都可以走路,也就是有一个走路方法,也叫动态属性
print("person is walking...")
类的定义
(2)类的作用
<1>属性引用
属性引用(类名.属性)
class Person: #定义一个人类
role = 'person' #人的角色属性都是人
def walk(self): #人都可以走路,也就是有一个走路方法
print("person is walking...") print(Person.role) #查看人的role属性
print(Person.walk) #引用人的走路方法,注意,这里不是在调用
属性引用
<2>实例化
语法:对象名 = 类名(参数)
类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征
实例化的过程就是类——>对象的过程
原本我们只有一个Person类,在这个过程中,产生了一个egg对象,有自己具体的名字、攻击力和生命值。
egg = Person('egon') #类名()就等于在执行Person.__init__()
#执行完__init__()就会返回一个对象。这个对象类似一个字典,存着属于这个人本身的一些属性和方法。
<3> 查看属性&调用方法
print(egg.name) #查看属性直接 对象名.属性名
print(egg.walk()) #调用方法,对象名.方法名()
<4> 关于self
self:在实例化时自动将对象/实例本身传给__init__的第一个参数,一般不做修改。
(3)类属性的补充
<1> 我们定义的类的属性到底存到哪里了?
有两种方式查看
dir(类名):查出的是一个名字列表
类名.__dict__:查出的是一个字典,key为属性名,value为属性值
<2> 特殊的类属性
类名.__name__# 类的名字(字符串)
类名.__doc__# 类的文档字符串
类名.__base__# 类的第一个父类(在讲继承时会讲)
类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
类名.__dict__# 类的字典属性
类名.__module__# 类定义所在的模块
类名.__class__# 实例对应的类(仅新式类中)
4. 对象的相关知识
对象是关于类而实际存在的一个例子,即实例
对象/实例只有一种作用:属性引用
动态属性:方法调用
print(egg.attack)
定义及调用的固定模式
class 类名:
def __init__(self,参数1,参数2):
self.对象的属性1 = 参数1
self.对象的属性2 = 参数2 def 方法名(self):pass def 方法名2(self):pass 对象名 = 类名(1,2) #对象就是实例,代表一个具体的东西
#类名() : 类名+括号就是实例化一个类,相当于调用了__init__方法
#括号里传参数,参数不需要传self,其他与init中的形参一一对应
#结果返回一个对象
对象名.对象的属性1 #查看对象的属性,直接用 对象名.属性名 即可
对象名.方法名() #调用类中的方法,直接用 对象名.方法名() 即可 小结
5. 对象之间的交互
实例化一只实实在在的二哈
ha2 = Dog('二愣子','哈士奇',10,1000) #创造了一只实实在在的狗ha2
交互 egon打ha2一下
print(ha2.life_value) #看看ha2的生命值
egg.attack(ha2) #egg打了ha2一下
print(ha2.life_value) #ha2掉了10点血
6. 类命名空间与对象、实例的命名空间
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
(1)类的两种属性
静态属性和动态属性
<1> 静态属性
直接在类中定义的变量——共享给所有对象的
<2> 动态属性
定义在类中的方法——绑定到所有对象的
class Course:
language = 'Chinese' # 静态属性
def __init__(self,teacher,name,period,price):
self.teacher = teacher,
self.name = name,
self.period = period,
self.price = price def func(self):
print('pass') python = Course('egon','python','6 months',20000)
linux = Course('eva','linux','6 months',20000)
示例代码
print(python.language) # English 类中的静态变量可以被对象调用
print(Course.language) # English 类中的静态变量可以被类调用
linux.func() # pass 类中的动态变量可以被对象调用
Course.func(linux) # pass 类中的动态变量可以被类调用(需要传参)
类中静/动态对象的调用
Course.language = 'English' # 静态属性修改
print(Course.language) # English 修改成功
# Course.__dict__['language'] = 'Chinese' # 不可以这么修改
# print(Course.language) # 报错
静态属性的修改:不能用dict修改
(2)静态变量的修改
<1> 类修改静态变量:
language = 'Chinese' 字符串【不可变数据类型】
<2> 对象修改静态属性
对于【不可变数据类型】来说
类变量最好用类名操作(如上例子)
因为用对象修改不是真正的修改,而是在对象自己的空间中创建新的同名属性
只有创建的同名属性删除后,才可以调用类中的静态属性
print(python.language) # English
print(linux.language) # English
python.language = 'Chinese' # 不能修改静态变量language,而是在自己的空间中创建了language的
print(python.language) # Chinese
print(python.__dict__) # {'teacher': ('egon',), ... , 'price': 20000, 'language': 'Chinese'}
print(linux.language) # English
print(linux.__dict__) # {'teacher': ('eva',), ... , 'price': 20000} del python.language # 自己创建的language删除之后,才能使用类中的静态变量
print(python.language) # English
对于【可变数据类型】来说
类中的静态变量:language = ['Chinese'] 列表【可变数据类型】
<1> 对象名的修改是共享的
python.language[0] = 'English'
print(python.language) # ['English']
print(python.__dict__) # {'teacher': ('egon',), ... , 'price': 20000}
print(linux.language) # ['English']
print(linux.__dict__) # {'teacher': ('eva',), ... , 'price': 20000}
<2> 对象名的重新赋值是独立的
python.language = 'English'
print(python.language) # English
python.language = ['English']
print(python.language) # ['English']
print(python.__dict__) # {'teacher': ('egon',), ... ,'price': 20000, 'language': 'English'}
print(linux.language) # ['Chinese']
print(linux.__dict__) # {'teacher': ('eva',), ... , 'price': 20000}
(3)应用举例
需求:创建一个类,每实例化一个对象就记录下来最终所有的对象共享这个数据
class Person:
count = 0
def __init__(self,name):
self.name = name
Person.count += 1
n1 = Person('gxx')
print(n1.count) #
n2 = Person('xcc')
print(n1.count) #
print(n2.count) #
n3 = Person('xcc')
print(n1.count) #
print(n2.count) #
print(n3.count) #
7. 认识绑定方法
# 函数 func
def func():
pass
print(func) # <function func at 0x000001FA4DC7F0D0> # 类中的方法 Foo.func
class Foo:
def func(self):
print('func类里')
f1 = Foo()
print(Foo.func) # <function Foo.func at 0x000001FA4DC7F2F0> # 对象调用方法的时候才有绑定方法
print(f1) # f1 <__main__.Foo object at 0x000001E57FE9E358>
print(f1.func) # f1对象的绑定方法<bound method Foo.func of <__main__.Foo object at 0x000001FA4DC7E358>>
# 把对象f1以self的形式传到方法中
8. 组合
组合:(面向对象的一种用法)
一个对象的属性值是另一个类的对象
class Dog:
def __init__(self,name,aggr,blood,kind):
self.name = name
self.aggr = aggr
self.blood = blood
self.kind = kind
def bite(self,person):
person.blood -= self.aggr class Person:
def __init__(self,name,aggr,blood,sex):
self.name = name
self.aggr = aggr
self.blood = blood
self.sex = sex
self.money = 0 def attack(self,dog):
dog.blood -= self.aggr def get_weapon(self,weapon):
if self.money >= weapon.price:
self.money -= weapon.price
self.weapon = weapon
self.aggr += weapon.aggr
else:
print('余额不足,请充值') class Weapon:
def __init__(self,name,aggr,njd,price):
self.name = name
self.aggr = aggr
self.njd = njd
self.price = price alex = Person('alex',1,10,'m')
jin = Dog('金老板',1000,500,'td')
w = Weapon('打狗棒',100,3,998) alex.attack(jin) # alex打了一下jin
print(jin.blood) # alex.money += 1000
alex.get_weapon(w)
print(alex.weapon) # <__main__.Weapon object at 0x000001C38FC64B70>
print(jin.blood) # alex.attack(jin) # alex用武器打了一下jin
print(jin.blood) #
人狗大战(有武器)
from math import pi
class Circle:
def __init__(self,r):
self.r = r
def zc(self):
return 2*pi*self.r
def mj(self):
return pi*self.r*self.r class Ring:
def __init__(self,outside_r,inside_r):
self.outside_c = Circle(outside_r)
self.inside_c = Circle(inside_r) def area(self):
return self.outside_c.mj() - self.inside_c.mj()
def perimeter(self):
return self.outside_c.zc() + self.inside_c.zc() ring = Ring(20,10)
print(ring.area())
print(ring.perimeter())
用组合实现:计算圆环的面积和周长
# 用组合实现:创建老师类,生日类,课程类,老师有生日,有课程信息 class Course:
def __init__(self,cname,price,time):
self.cname = cname
self.price = price
self.time = time
class Birthday:
def __init__(self,year,month,day):
self.year = year
self.month = month
self.day = day
class Teacher:
def __init__(self,tname,sex,age,courseinfo,birth):
self.tname = tname
self.sex = sex
self.age = age
self.birth = birth
self.course = courseinfo b = Birthday(1996,7,18)
c = Course('Linux',2000,'2 days')
t = Teacher('xc','f',22,c,b)
print('老师姓名:' + t.tname) # 老师姓名:xc
print(t.birth.year) #
print('课程价格:' + str(t.course.price)) # 课程价格:2000
组合应用实例
借鉴:http://www.cnblogs.com/Eva-J/articles/7293890.html#_label1
Python——面向对象、绑定对象、组合的更多相关文章
- python 面向对象 继承 派生 组合
具体参考博客:http://www.cnblogs.com/linhaifeng/articles/6182264.html#_label12 一.面向对象 面向对象:对象与对象之间的相互交互,不可预 ...
- python面向对象中类对象、实例对象、类变量、实例变量、类方法、实例方法、静态方法
1. 类对象和实例对象 Python中一切皆对象,Python类本身也是一种对象,类定义完成后,会在当前作用域中定义一个以类名为名字的命名空间.类对象具有以下两种操作: 可以通过“类名()”的方式实例 ...
- python面向对象编程 继承 组合 接口和抽象类
1.类是用来描述某一类的事物,类的对象就是这一类事物中的一个个体.是事物就要有属性,属性分为 1:数据属性:就是变量 2:函数属性:就是函数,在面向对象里通常称为方法 注意:类和对象均用点来访问自己的 ...
- python面向对象的继承-组合-02
*面向对象(OOP)的三大特征:**# 封装.继承.多态 继承 什么是继承 继承:# 是一种关系,描述两个对象之间什么是什么的什么的关系 例如:麦兜.佩奇.猪猪侠.猪刚鬣,都是猪 为什么要使用继承 继 ...
- python面向对象之类的组合
一.python类的组合:给一个类的对象封装一个属性,这个属性是另一个类的对象二.组合的意义:让类的对象与另一个类的对象产生关系,类与类之间产生关系.三.例子模拟英雄联盟写一个游戏人物的类 要求:(1 ...
- Python面向对象-获取对象信息type()、isinstance()、dir()
type() type()函数用于判断对象类型: >>> type(11) <class 'int'> >>> type('abc') <clas ...
- python面向对象编程对象和实例的理解
给你一个眼神,自己体会
- python 面向对象之多态与绑定方法
多态与多态性 一,多态 1,多态指的是一类事物有多种形态(python里面原生多态) 1.1动物有多种形态:人,狗,猪 import abc class Animal(metaclass=abc.AB ...
- Python面向对象02/类的空间问题、类与对象之间的关系、类与类之间的关系
Python面向对象02/类的空间问题.类与对象之间的关系.类与类之间的关系 目录 Python面向对象02/类的空间问题.类与对象之间的关系.类与类之间的关系 1. 类的空间问题 2. 类与对象之间 ...
- python 面向对象专题(二):类的空间问题、类与对象之间的关系、类与类之间的关系
https://www.cnblogs.com/liubing8/p/11308127.html 目录 Python面向对象02/类的空间问题.类与对象之间的关系.类与类之间的关系 1. 类的空间问题 ...
随机推荐
- iOS UI-界面传值(三种方法)
#import <Foundation/Foundation.h> @interface DataModel : NSObject @property (nonatomic, copy) ...
- SSH 不分配远程主机tty
$ host N参数,表示只连接远程主机,不打开远程shell:T参数,表示不为这个连接分配TTY.这个两个参数可以放在一起用,代表这个SSH连接只用来传数据,不执行远程操作.
- Centos7上部署openstack mitaka配置详解(将疑难点都进行划分)
在配置openstack项目时很多人认为到处是坑,特别是新手,一旦进坑没有人指导,身体将会感觉一次次被掏空,作为菜鸟的我也感同身受,因为已经被掏空n次了. 以下也是我将整个openstack配置过程进 ...
- mysql创建索引-----高性能(五)
转载地址:https://www.cnblogs.com/llzhang123/p/7889382.html 索引的创建可以在CREATE TABLE语句中进行,也可以单独用CREATE INDEX或 ...
- 063——VUE中vue-router之重定向redirct的使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- spoj375
题解: 树链剖分的模板题 具体代码详见网上的其他代码 代码: #include<cstdio> #include<cmath> #include<cstring> ...
- 获取jsp选中复选框的id传到后台controller,进行逻辑删除等操作
逻辑删除设备:(数据表中还有这条记录,不显示出来) 思路: 数据表加个字段display,值为Y/N,只显示display为Y的,删除时,把display的值改为N,就不会显示出来 jsp页面如下图, ...
- Programming Contest Ranking(题解)
Programming Contest Ranking . 题目描述 Heilongjiang Programming Contest will end successfully! And your ...
- 团队作业之现场UML设计
项目UML设计(团队) 团队信息 团队名:第三视角 各成员学号及姓名 姓名 学号 博客链接 张扬(组长) 031602345 http://www.cnblogs.com/sxZhangYang/p/ ...
- axure 认证授权注册码2017-12-25
Licensee: University of Science and Technology of China (CLASSROOM)Key: DTXRAnPn1P65Rt0xB4eTQ+4bF5IU ...