python学习笔记——第七章 更加抽象(对象)

第七章 更加抽象(对象)

1、几个概念
多态:对不同类的对象使用同样的操作。
封装:对外部世界隐藏对象的工作细节。
继承:以普通那的类为基础建立专门的类对象。

多态例子:

>>> 'abc'.count('a')
1
>>> [1,2,'a'].count('a')
1

repr(obj):得到obj的表示字符串,可以利用这个字符串用eval函数重建该对象的一个拷贝
eval(str):str是一个字符串,表示合法的python表达式,返回这个表达式
>>> def length_message(x):
	print("The lenght of", repr(x), "is", len(x))

	
>>> length_message('Fnord')
The lenght of 'Fnord' is 5
>>> length_message([1,2,3])
The lenght of [1, 2, 3] is 3

2、新式类
在模块或者脚本开始的地方放置赋值语句 __metaclass__ = type

>>> __metaclass__ = type
>>> class Person:
	def setName(self,name):
		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('jack wang')
>>> bar.setName('leng leng')
>>> foo.greet()
Hello,world! I'm jack wang. 
>>> bar.greet()
Hello,world! I'm leng leng. 
>>> 
>>> foo.name
'jack wang'
>>> bar.name = 'Yoda'  #特性可以在外部访问的
>>> bar.greet()
Hello,world! I'm Yoda. 
3、特性、函数和方法 
将属性绑定到一个函数上

>>> class Class:
	def method(self):
		print('I have a self!')

		
>>> def function():
	print("I don't...")

	
>>> instance = Class()
>>> instance.method()
I have a self!
>>> instance.method()
I have a self!
>>> instance.method = function  #将属性绑定到普通函数 
>>> instance.method()
I don't...

self参数引用同一个方法的其他变量

>>> class Bird:
	song = 'Squaawk!'
	def sing(self):
		print(self.song)

		
>>> bird = Bird()
>>> bird.sing()
Squaawk!
>>> birdsong = bird.sing
>>> birdsong()
Squaawk!

私有属性、方法——Python并没有真正的私有化支持,但可用下划线得到伪私有
尽量避免定义以下划线开头的变量
(1)_xxx      "单下划线 " 开始的成员变量叫做保护变量,意思是只有类对象(即类实例)和子类对象自己能访问到这些变量,需通过类提供的接口进行访问;不能用'from module import *'导入
(2)__xxx    类中的私有变量/方法名 (Python的函数也是对象,所以成员方法称为成员变量也行得通。)," 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。
(3)__xxx__ 系统定义名字,前后均有一个“双下划线” 代表python里特殊方法专用的标识,如 __init__()代表类的构造函数。
 
  __开头的本来就是表示private,private是不可继承的


  为了让方法或者特性变为私有(从外部无法访问),只要在它的名字前面加上双下划线即可:

	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#31>", line 1, in <module>
    s.__inaccessible()
AttributeError: 'Secretive' object 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 C:
	print('Class C being defined...')  #在类的定义区并不只限使用def语句

	
Class C being defined...


以下代码中类作用域内定义了一个可供所有成员(实例)访问的变量,用来计算类的成员数量
>>> class MemberCounter:
	members = 0
	def init(self):
		MemberCounter.members += 1

		
>>> m1 = MemberCounter()
>>> m1.init()
>>> MemberCounter.members
1
>>> m2 = MemberCounter()
>>> m2.init()
>>> MemberCounter.members
2

# 类作用域内的变量也可以被所有实例访问
>>> m1.members
2
>>> m2.members
2

>>> m1.members = 'Two' #在实例中重绑定members特性
>>> m1.members
'Two'
>>> m2.members
2

5、指定超类---将其他类名写在class语句后的圆()内可以指定超类

>>> 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
<bound method SPAMFilter.init of <__main__.SPAMFilter object at 0x013D0590>>
>>> s.init()
>>> s.filter(['SPAM','SPAM','SPAM','SPAM','eggs','bacon','SPAM'])  #可以将SPAM过滤出去
['eggs', 'bacon']

6、调用继承
内建issubclass函数:查看一个类是否是另一个的子类

>>> issubclass(SPAMFilter,Filter)
True
>>> issubclass(Filter,SPAMFilter)
False

想知道已知类的基类(们),使用它的特殊特性__bases__

>>> SPAMFilter.__bases__
(<class '__main__.Filter'>,)
>>> Filter.__bases__
(<class 'object'>,)

isinstance():检查一个对象是否是一个类的实例

>>> s = SPAMFilter()
>>> isinstance(s,SPAMFilter)  #s是SPAMFilter类的直接成员
True
>>> isinstance(s,Filter) #s是Filter类的间接成员
True
>>> isinstance(s,str)
False

对象属于哪个类,使用__class__特性

>>> s.__class__
<class '__main__.SPAMFilter'>

7、多个超类 (多重继承)

>>> 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') #子类调用超类的 calculate()方法 
>>> tc.talk()   #子类调用超类的 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放在前面

8、接口和内省----——公开的方法和属性
检查所需方法(特性)是否存在

>>> hasattr(tc, 'talk')  #对象tc有talk特性
True
>>> hasattr(tc, 'fnord')   #对象tc没有fnord特性
False

检查方法是否可调用

>>> hasattr(getattr(tc,'talk',None),'__call__')
True
>>> hasattr(getattr(tc,'fnord',None),'__call__')
False

getattr()允许提供默认值,以便当方法不存在时使用。
与getattr相对应的是setattr,可以用来设置对象的特性;

>>> setattr(tc,'name','Jack') #设置对象的特性
>>> tc.name
'Jack'

查看对象内所有存储的值,可以使用__dict__特性

>>> tc.__dict__
{'name': 'Jack', 'value': 7}

总结:
对象:对象包括特性和方法,特性只是作为对象的一部分变量,方法则是存储在对象内的函数
     (绑定)方法和其他函数的区别在于方法总是将对象作为自己的第一个参数,这个参数一般称为self
类:类代表对象的集合(或一类对象),每个对象(实例)都有一个类,类的主要任务是定义任务是定义它的实例会用到的方法。
多态:多态是实现将不同类型和类的对象进行同样对待的特性---不需要知道对象属于哪个类就能调用方法。
封装:对性可以将它们的内部状态隐藏起来。
继承:一个类可以是一个或多个类的子类。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值