python学习笔记六 初识面向对象上(基础篇)
- 写重复代码是非常不好的低级行为
- 你写的代码需要经常变更
#定义一个字典, 所有的角色的变量名都是一样的,但调用的时候又能区分开分别是谁。
roles = {
:{'name':'Alex',
'role':'terrorist',
'weapon':'AK47',
'life_value': ,
'money': ,
},
:{'name':'Jack',
'role':'police',
'weapon':'B22',
'life_value': ,
'money': ,
},
:{'name':'Rain',
'role':'terrorist',
'weapon':'C33',
'life_value': ,
'money': ,
},
:{'name':'Eirc',
'role':'police',
'weapon':'B51',
'life_value': ,
'money': ,
},
} #print(roles[])#Alex
#print(roles[]) #Jack def shot(by_who):
#开了枪后要减子弹数
pass
def got_shot(who):
#中枪后要减血
who[‘life_value’] -=
pass
def buy_gun(who,gun_name):
#检查钱够不够,买了枪后要扣钱
pass
继续按照这个思路设计,再完善一下代码,游戏的简单版就出来了,但是在往下走之前,我们来看看上面的这种代码写法有没有问题,至少从上面的代码设计中,我看到以下几点缺陷:
.无法确保新添加角色时,他们的属性定义是否正确。
比如 weapon 拼写错误程序无法检测; .角色间无法区分不同的功能
警察和匪徒有不同的功能用函数式编写大家都可以调用,无法区分; .添加新的属性都要添加一遍
假设要新添加防弹衣功能,需要在字典中每个角色都要添加; .每个功能使用相同属性都要重新传入一遍
buy_gun,got_shot每次调用都要传入name; .我们在上面定义了got_shot()后要减血,也就是说减血这个动作是应该通过被击中这个事件来引起的,
但其实我不通过got_shot(),直接调用角色roles[role_id][‘life_value’] 减血也可以.
使用面向对象实现:
class Role(object):
def __init__(self,name,role,weapon,life_value=,money=):
self.name = name
self.role = role
self.weapon = weapon
self.life_value = life_value
self.money = money def shot(self):
print("shooting...") def got_shot(self):
print("ah...,I got shot...") def buy_gun(self,gun_name):
print("just bought %s" %gun_name) r1 = Role('Alex','police','AK47’) #生成一个角色
r2 = Role('Jack','terrorist','B22’) #生成一个角色
- 代码量少了近一半
- 角色和它所具有的功能可以一目了然看出来
面向对象三大特性
类在实例化 (把一个抽象的类变成一个具体的对象的过程叫做实例化 )对象的时候,会执行初始化方法。 class person(object):
def __init__(self,name,age):
self.name = name
self.age = age obj1 = person('koka',) <=> person.__init__(obj1,'koka',) 解析:
你执行obj1 = person('koka',)时,python的解释器其实干了两件事: .在内存中开辟一块空间指向obj1这个变量名 .调用person这个类并执行其中的__init__(…)方法,相当于person.__init__(obj1,'koka',),这么做是为什么呢?
是为了把'koka',24这2个值跟刚开辟的obj1关联起来,因为关联起来后,你就可以直接obj1.name, obj1.age 这样来调用啦。
所以,为实现这种关联,在调用__init__方法时,就必须把obj1这个变量也传进去,否则__init__不知道要把那2个参数跟谁关联呀。
所以这个__init__(…)方法里的,self.name = name , self.role = role 等等的意思就是要把这几个值存到obj1的内存空间里。
继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。
例如:
猫可以:喵喵叫、吃、喝、拉、撒
狗可以:汪汪叫、吃、喝、拉、撒
如果我们要分别为猫和狗创建一个类,那么就需要为 猫 和 狗 实现他们所有的功能,如下所示:
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()
所以,对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。
注:除了子类和父类的称谓,你可能看到过 派生类 和 基类 ,他们与子类和父类只是叫法不同而已。
学习了继承的写法之后,我们用代码来是上述阿猫阿狗的功能:
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() 代码实例
继承实例
继承重写
class AddrBookEntry(object):
'address book entry class'
def __init__(self,nm,ph):
self.name = nm
self.ph = ph
print("Created instance for:",self.name)
def UpdatePhone(self,newph):
self.ph = newph
print('Updated phone %s for:'%self.ph ,self.name) class EmplAddrBookEntry(AddrBookEntry):
'Employee Address Book Entry class'
def __init__(self,nm,ph,id,em): #重写init
super(EmplAddrBookEntry,self).__init__(nm,ph) #继承父类的init
#AddrBookEntry.__init__(self,nm,ph)
self.empid = id
self.email = em
def updateEmail(self,newem):
self.email = newem
print('Updated e-mail address %s for:'%self.email,self.name) new = AddrBookEntry("koka",'') #父类生成实例
new.UpdatePhone("") #使用方法更新
newnew = EmplAddrBookEntry("akok","","","wlgc.com") #子类生成实例 继承父类的nm,ph 重写id,em
newnew.updateEmail("12345@qq.com") #子类实例使用自己的方法
newnew.UpdatePhone("") #子类实例继承使用父类方法
多重继承
import time
class A(object):
n = 'A'
def f2(self):
print("f2 from A")
def f1(self):
print("f1 from A")
class B(A):
n = 'B'
def f1(self):
print("f1 from B")
#def f2(self):
# print("f2 from B") class C(A):
n = 'C'
def f1(self):
print("f1 from C")
def f2(self):
print("f2 from C") class D(B,C):
n = 'D'
def __del__(self):
#会在程序结束后执行,释放内存
print("deleting the ...") d = D()
d.f1() #输出 f1 from B
d.f2() #输出 f2 from C # 新式类:D -> B -> C -> A 广度查找(从左至右查找最近的)
# 经典类: D-> B -> A 深度查找,在python3.0以后默认为广度查找
多态
实例:
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
def talk(self): # Abstract method, defined by convention only
raise NotImplementedError("Subclass must implement abstract method") class Cat(Animal):
def talk(self):
return 'Meow!' class Dog(Animal):
def talk(self):
return 'Woof! Woof!' animals = [Cat('Missy'),
Dog('Lassie')] for animal in animals:
print animal.name + ': ' + animal.talk()
"""
def animal_talk(obj):
print(obj.talk()) d = Dog("sanjiangyuan")
c = Cat("sanjiangshui")
animal_talk(c)
animal_talk(d)
"""
python学习笔记六 初识面向对象上(基础篇)的更多相关文章
- Python学习笔记整理总结【语言基础篇】
一.变量赋值及命名规则① 声明一个变量及赋值 #!/usr/bin/env python # -*- coding:utf-8 -*- # _author_soloLi name1="sol ...
- python学习笔记五 模块下(基础篇)
shevle 模块 扩展pickle模块... 1.潜在的陷进 >>> import shelve>>> s = shelve.open("nb" ...
- python学习笔记三 文件操作(基础篇)
文件操作 打开文件 open(name[,mode[,buffering]]) open函数使用一个文件名作为强制参数,然后返回一个文件对象.[python 3.5 把file()删除掉] w ...
- Python学习-第三天-面向对象编程基础
Python学习-第三天-面向对象编程基础 类和对象 简单的说,类是对象的蓝图和模板,而对象是类的实例.这个解释虽然有点像用概念在解释概念,但是从这句话我们至少可以看出,类是抽象的概念,而对象是具体的 ...
- Python学习笔记六
Python课堂笔记六 常用模块已经可以在单位实际项目中使用,可以实现运维自动化.无需手工备份文件,数据库,拷贝,压缩. 常用模块 time模块 time.time time.localtime ti ...
- python学习笔记——多进程间通信——Linux信号基础
1 信号的基本描述 Signal信号(其全程为软中断信号)是Linux系统编程中非常重要的概念,信号是异步进程中通信的一种方式. 作用是通知进程发生了异步事件.进程之间可以调用系统来传递信号, 本身内 ...
- python学习笔记六 面向对象相关下(基础篇)
面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以将多函数中公用的变量封装到对象中) 对象,根据模板创建的 ...
- python 学习笔记9(面向对象)
面向过程.函数式.面向对象 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象(Object Oriented Programmin ...
- python学习日记(初识面向对象)
面向过程 VS 面向对象 面向过程 面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行.为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统 ...
随机推荐
- 直关的sql 联级更新语句
在sql-server中用这种写法最直观:UPDATE a SET a.c = b.c FROM table1 ainner join table2 b on b.a=a.aWHERE a.c is ...
- Android bindservice使用
package com.example.myact10; import com.example.myact10.MyService.MyBinder; import android.support.v ...
- Inside TSQL Querying - Chapter 2. Physical Query Processing
Summary Description The SQL language is spoken by most database experts, and all relational database ...
- Java如何对ArrayList里的元素排序
- APP的UI测试要点
1.文字显示是否正确 比如与需求图片对比是否正确,无错别字 2.对齐方式是否正确 3.图片 图片显示的篇幅不要太大. 4.颜色是否正确 颜色与需求规定的是否一致
- 【python cookbook】【数据结构与算法】17.从字典中提取子集
问题:想创建一个字典,其本身是另一个字典的子集 解决方案:利用字典推导式(dictionary comprehension)可轻松解决 # example of extracting a subset ...
- Mac下好用的取色器 Sip
总有很多东西,你只是望一眼就已经神魂颠倒.措施有这样的App做的真的是用心的很,养眼,触发你内心冲动的美感.先留下一个,备忘. 太精致了 操作简单,左上角的有心圆点击就可以在任何地方取色了,取色点会z ...
- android 开发中的常见问题
Android studio 使用极光推送, 显示获取sdk版本失败 在 build.gradle(Module.app) 添加 android { sourceSets.main { ...
- ImageLoader 图片加裁
// String picurl = article.cateLogo;// ImageLoader.getInstance().displayImage(picurl, holder.cate_Lo ...
- Python学习总结:目录
Python 3.x总结 Python学习总结[第一篇]:Python简介及入门 Python学习总结[第二篇]:Python数据结构 Python学习总结[第三篇]:Python之函数(自定义函数. ...