第七章 更加抽象——面向对象
1. 面向对象的特点——多态,封装,继承
对象:包括特性和方法,特性只是作为对象的一部分变量,而方法则是存储在对象内的函数。
(1)多态——对不同类的对象,使用同样操作。不知道对象到底是什么类型,但又要对对象做一些操作
很多内置的函数和运算符都是多态的
不用关注x到底是什么类型,都可以使用count函数,另外还有repr(),连接符+等
>>> x = 'string' #x是字符串
>>> x.count('s')
1
>>> x = ['1', '2', '1'] #x是列表
>>> x.count('1')
2
(2)封装——对外部世界隐藏对象的操作细节
(3)继承——以普通类为基础建立专门的类对象
2. 创建类
对于python来说,方法就分两种一种是绑定的,一种是不绑定。属于类的方法就是绑定的,普通的函数就是不绑定的
除了静态类,其他类的方法定义时都需要有一个self参数,而调用时不需要,self类似java/c++里的this,不是指类本身,而是指实例本身。
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,但是在调用这个方法的时候你不
为这个参数赋值,Python会提供这个值。这个特别的变量指对象本身,按照惯例它的名称是self
。
self原理:举例说明,有一个类A,A的实例a,a.method(arg1,arg2)这时python自动转A.method(a,arg1,arg2),这也意味着如果你有一个不需要参数的方法,你还是得给这个方法定义一个self
参数。
python没法显式的说哪个属性是自己的,而且属性还可以动态的增加,此时,一个解决方案出来了,增加self,通过self.访问的就可以做为类的属性。
>>> _metaclass_ = type #确定使用新类
>>> class Person:
def setName(self, name): #相当于this,代表Person对象自身
self.name = name
def getName(self):
return self.name
def greet(self):
print "Hello, world! I'm %s." %self.name
#运行
>>> foo = Person()
>>> bar = Person()
>>> foo.setName('Luke') #相当于给实例foo,添加了一个attribute: name
>>> bar.setName('Anakin')
>>> foo.greet()
Hello, world! I'm Luke.
>>> bar.greet()
Hello, world! I'm Anakin.
>>> foo.name #特性可在外部访问
'Luke'
>>> Person.getName(foo) #效果同上
'Luke'
>>> bar.name = 'Yoda' #特性也可在外部直接修改,类似bar.setName('Yoda')
>>> bar.greet() #等价于Person.greet(bar)
Hello, world! I'm Yoda.
将属性绑定到普通函数上
>>> class MyClass:
def method(self):
print "I have a self!"
>>> def function():
print "I don't..."
>>> c = MyClass()
>>> c.method()
I have a self!
>>> c.method = function #将属性绑定到普通函数
>>> c.method()
I don't...
3. 私有属性、方法——Python并没有真正的私有化支持,但可用下划线得到伪私有
尽量避免定义以下划线开头的变量
(1)_xxx
"单下划线
"
开始的成员变量叫做保护变量,意思是只有类对象(即类实例)和子类对象自己能访问到这些变量,需通过类提供的接口进行访问;不能用'from module import *'导入
(2)__xxx
类中的私有变量/方法名
(Python的函数也是对象,所以成员方法称为成员变量也行得通。),"
双下划线
"
开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。
(3)__xxx__ 系统定义名字,前后均有一个“双下划线”
代表python里特殊方法专用的标识,如
__init__()代表类的构造函数。
__开头的本来就是表示private,private是不可继承的
python有私有的定义方法就是在变量或者方法的面前加上双下滑线__,但是实际上这是python的伪私有。只是一种程序员约定俗称的规定,加了就表示私有变量,但是如果要在外部调用的话,还是可以调用的,调用方法如下:
所有以双下划线开始的变量,都被python翻译为前面加上单下划线和类名
如__inaccessible 翻译为 Secretive._Secretive__inaccessible,注意第一个为单下划线,第二个为双下划线
>>> class Secretive:
def __inaccessible(self): #双下划线表示私有方法
print "Bet you can't see me..."
def accessible(self):
print "The secret message is:"
self.__inaccessible()
>>> s = Secretive()
>>> s.__inaccessible() #私有方法从外界是无法访问的
Traceback (most recent call last):
File "<pyshell#89>", line 1, in <module>
s.__inaccessible() #私有方法从外界是无法访问的
AttributeError: Secretive instance has no attribute '__inaccessible'
>>> s.accessible() #私有方法只能在类内部使用
The secret message is:
Bet you can't see me...
>>> s._Secretive__inaccessible() #虽然私有,仍能调用,伪私有机制
Bet you can't see me...
4. 类的命名空间——class语句中的代码都在特殊的命名空间中执行
类的定义区并不只限定使用def语句
>>> class C:
print 'Without def...'
#运行
Without def...
计算类的实例数量
>>> class MemberCounter:
members = 0
def init(self):
MemberCounter.members += 1 #属于整个类的属性members,计算类的实例数量,而不用self.members,实例的属性
>>> m1 = MemberCounter()
>>> m1.init()
>>> MemberCounter.members
1
>>> m1.members
1
>>> m2 = MemberCounter()
>>> m2.init()
>>> MemberCounter.members
2
>>> m2.members #类作用于内的变量,可以被所有实例访问
2
>>> m1.members
2
>>> m2.members = 'test' #重绑定members,相当于新添加了与类里的members相同的同名变量,从而屏蔽了类范围内的变量
>>> m2.members
'test'
>>> m1.members #不变
2
>>> MemberCounter.members
2
5. 继承
格式:A是父类,B是子类,B继承A
class A:
class B(A):
>>> class Filter:
def init(self):
self.blocked = []
def filter(self, sequence):
return [x for x in sequence if x not in self.blocked]
>>> class SPAMFilter(Filter): #继承Filter
def init(self): #重写Filter父类中的init方法
self.blocked = ['SPAM']
>>> f = Filter()
>>> f.init()
>>> f.filter([1, 2, 3])
[1, 2, 3]
>>>
>>> s = SPAMFilter()
>>> s.init() #调用子类重写的方法
>>> s.filter(['SPAM', 'TEST', 'SPAM', 'test']) #调用从父类继承来的方法
['TEST', 'test']
调查继承
issubclass(A,B):查看类A是否是类B的子类
>>> issubclass(SPAMFilter, Filter)
True
>>> issubclass(Filter, SPAMFilter)
False
若想知道某个类的基类,使用特殊属性__bases__,注意为“双下划线”
>>> SPAMFilter.__bases__
(<class __main__.Filter at 0x011A62D0>,)
>>> Filter.__bases__
()
isinstance(A,B):对象A是否是类B的实例
>>> s = SPAMFilter() #既是子类的实例又是父类的实例
>>> isinstance(s, SPAMFilter) #s是子类的直接实例(成员)
True
>>> isinstance(s, Filter) #s是父类的间接实例
True
>>> isinstance(s, str) #isinstance对类型也起作用,如str是字符串类型
False
若想知道对象属于哪个类的实例,使用特殊属性__class__,注意为“双下划线”
>>> s.__class__
<class __main__.SPAMFilter at 0x011A6480>
6. 多重继承
子类TalkingCalculator不作任何事,它从父类中继承所有的行为,从Calculator中继承calculate方法,从Talk中继承talk方法。
>>> class Calculator:
def calculate(self, expression):
self.value = eval(expression)
>>> class Talker:
def talk(self):
print "Hi, my value is", self.value
>>> class TalkingCalculator(Calculator, Talker):
pass
>>> tc = TalkingCalculator()
>>> tc.calculate('1 + 2 * 3')
>>> tc.talk()
Hi, my value is 7
注意超类顺序,先继承的类中的方法会重写后继承的类中的方法
假设C继承A和B,而A和B中有同名方法,如method
class C(A, B):,A中的method重写B中的method
class C(B, A):,B中的method重写A中的method,所以如果想使用B中的method方法,则将B放在前面
7. 接口和内省——公开的方法和属性
检查所需方法(特性)是否存在
>>> hasattr(tc, 'talk')
True
>>> hasattr(tc, 'test')
False
检查方法是否可调用
>>> hasattr(getattr(tc, 'talk', None), '__call__')
True
>>> hasattr(getattr(tc, 'test', None), '__call__')
False
getattr()允许提供默认值,以便当方法不存在时使用。
与getattr()相对的是setattr()用来设置对象特性
>>> setattr(tc, 'name', 'Mr. Gumby')
>>> tc.name
'Mr. Gumby'
总结:
random.choice(seq) : 从非空序列中随机选择元素
>>> from random import choice
>>> choice([1, 2, 3])
1
type(object):返回对象类型
>>> type('test')
<type 'str'>
>>> type(1)
<type 'int'>
分享到:
相关推荐
Python 笔记源码——内含python后端&机器学习等.zip Python 笔记源码——内含python后端&机器学习等.zip Python 笔记源码——内含python后端&机器学习等.zip Python 笔记源码——内含python后端&机器学习等.zip ...
python 学习笔记——线性回归预测模型.pdf python 学习笔记——线性回归预测模型.pdf python 学习笔记——线性回归预测模型.pdf python 学习笔记——线性回归预测模型.pdf python 学习笔记——线性回归预测模型.pdf ...
Python学习笔记——对象和类
Python深度学习实战——基于Pytorch全书电子教案完整版ppt整套教学课件最全教学教程.pptx
Python学习笔记——运算符 运算符: 赋值运算符 算术运算符 关系运算符 逻辑运算符 位运算
Python学习笔记——输入input(),input()使用,两个练习。
Python从入门到精通 第7章 字符串.ppt Python从入门到精通 第8章 Python中使用正则表达式.ppt Python从入门到精通 第9章 函数.ppt Python从入门到精通 第10章 面向对象程序设计.ppt Python从入门到精通 第11章 模块....
Python学习笔记 .pdf Python学习笔记 .pdf Python学习笔记 .pdf Python学习笔记 .pdf Python学习笔记 .pdf Python学习笔记 .pdf Python学习笔记 .pdf Python学习笔记 .pdf Python学习笔记 .pdf Python学习笔记 .pdf ...
对应Python学习笔记——变量、print、转义字符。变量的类型、命名规则、print的用法、字符串的表示以及转义字符
python学习笔记1——(廖雪峰教程,菜鸟教程)python基础 python学习笔记1——(廖雪峰教程,菜鸟教程) >>> classmates = ['Michael', 'Bob', 'Tracy'] >>> len(classmates) 3 ⽤索引来访问list中每⼀个位置的元素...
Python学习笔记——socket通信相关资源文件 内部包括server1 2 3 + windows版 nc
CSP202109-2 非零段划分 学习笔记 python(csdn)————程序
python训练营python学习笔记(csdn)————程序
[实训解析]Python 计算思维训练——SAR图像处理-第2关:读入一个目录下所有图像_5307.pdf
用Python学习线性代数——向量在Jupyter Notebook下运行的文件,内容包括行列向量的基本表示,向量的基本运算等。详情请见https://tuenity.blog.csdn.net/article/details/104070768。
python计算机视觉学习————图像内容分类 计算机视觉.pdf
关于python面向对象知识点的ppt,用于学生作presentation,内容还包括案例源码
Python深度学习实战——基于Pytorch-ppt.zip