Python基础教程之第7章 更加抽象

D:\>python
Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
# Chapter 07 更加抽象
#7.1 对象的魔力
# 前几章介绍了Python主要的内建对象类型(数字, 字符串, 列表, 元组和字典),以及内建函数和标准库的用法,还有自定义函数的方式.
# 本章介绍如何创建自己的对象.
#7.1 对象的魔力
#多态: Polymorphism
#封装: Encapsulation
#继承: Inheritance
#7.1.1 多态
>>> #object.getPrice()
...
>>> 'abc'.count('a')
1
>>> [1,2,'a'].count('a')
1
>>> from random import choice

>>> x=choice(['Hello, world', [1,2,'e','e',4]])
>>>
>>> x
'Hello, world'
>>> x.count('e')
1
>>> x=choice(['Hello, world', [1,2,'e','e',4]])
>>> x
[1, 2, 'e', 'e', 4]
>>> x.count('e')
2
>>> 1+2
3
>>> 'Fish' + 'license'
'Fishlicense'
>>> def add(x,y):
...     return x+y
...
>>> add(1,2)
3
>>> add('Fish','license')
'Fishlicense'
>>> def length_message(x):
...     print "The length of", repr(x), "is", len(x)
...
>>> length_message('Fnord')
The length of 'Fnord' is 5
>>> length_message([1,2,3])
The length of [1, 2, 3] is 3

#7.1.2 封装

#7.1.3 继承
#7.2 类和类型
#7.2.1 类到底是什么
#7.2.3 创建自己的类

>>> __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('Luke Skywalker')
>>> bar.setName('Anakin Skywalker')
>>> foo.greet()
Hello, world! I'm Luke Skywalker.
>>> bar.greet()
Hello, world! I'm Anakin Skywalker.
>>> foo.name
'Luke Skywalker'
>>> bar.name
'Anakin Skywalker'
>>> bar.name='Yoda'
>>> bar.greet()
Hello, world! I'm Yoda.
>>> Person.greet(bar)
Hello, world! I'm Yoda.
>>> Person.greet(foo)
Hello, world! I'm Luke Skywalker.
>>>

#7.2.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 = function
>>> instance.method
<function function at 0x00BB2830>
>>> def my_func():
...     print "I don't..."
...
>>> instance.method=my_func
>>> instance.method
<function my_func at 0x00BB28F0>
>>>
>>> class Bird:
...     song = 'Squaark!'
...     def sing(self):
...             print self.song
...
>>> bird=Bird()
>>> bird.sing()
Squaark!
>>> birdsong = bird.sing
>>> birdsong()
Squaark!
>>>
>>> class Secretive:
...     def __inaccessible(self):
...             print "Bet your can't see me..."
...
# 类的内部定义中, 所有以双下划线开始的名字都被"翻译"为前加 单下划线 和 类名 的形式

# 如果想让其他对象不要访问内部数据, 那么可以使用单下划线
# 前面有下划线的名字都不会被带星号的imports语句(from module import *)
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.__inaccessibl()
#python tt.py
#Traceback (most recent call last):
#  File "tt.py", line 9, in <module>
#    s.__inaccessibl()
#AttributeError: Secretive instance has no attribute '__inaccessibl'

s.accessible()
#The secret message is:
#Bet you can't see me...

Secretive._Secretive__inaccessible

s._Secretive__inaccessible()
#Bet you can't see me...


#7.2.4 类的命名空间
>>> class C:
...     print 'Class C being defined...'
...
Class C being defined...
>>>

class MemberCounter:
	members = 0;
	def init(self):
		MemberCounter.members +=1
	
m1 = MemberCounter()
m1.init()
print MemberCounter.members


m2 = MemberCounter()
m2.init()
print MemberCounter.members

print m1.members
print m2.members

m1.members = 'Two'
print m1.members
print m2.members
print MemberCounter.members

#python tta.py
#1
#2
#2
#2
#Two
#2
#2

#7.2.5 指定超类
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): #SPAMFilter is subclass of Filter
	def init(self): # over-write init method from Filter
		self.blocked = ['SPAM']
		
f = Filter()
f.init()
print f.filter([1,2,3])
#python ttb.py
#[1, 2, 3]

s = SPAMFilter()
s.init()
print s.filter(['SPAM', 'SPAM', 'SPAM', 'SPAM', 'eggs', 'bacon', 'SPAM'])

#['eggs', 'bacon']

print issubclass(SPAMFilter, Filter)
print issubclass(Filter, SPAMFilter)
#True
#False

print SPAMFilter.__bases__
print Filter.__bases__
#(<class __main__.Filter at 0x00AF7A78>,)
#()

print isinstance(s, SPAMFilter)
print isinstance(s, Filter)
print isinstance(s, str)
#True
#True
#False

print s.__class__
#__main__.SPAMFilter

#7.2.6 调查继承
#多个超类

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()
print tc.calculate('1+2*3')
print tc.talk()

print hasattr(tc, 'talk')
print hasattr(tc, 'fnord')

callable(getattr(tc, 'talk', None))
callable(getattr(tc, 'fnord', None))
setattr(tc, 'name', 'Mr. Gumby')
print tc.name

#python ttc.py
#None
#Hi, my value is 7
#None
#True
#False
#Mr. Gumby

#7.2.8 接口和内省
# inspect模块

#一些关于面向对象设计的思考
#将属于一类的对象放在一起. 如果一个函数操纵一个全局变量, 那么二者最好都在类内作为特性和方法出现.
#不要让对象过于亲密. 方法应该只关心自己实例的特性.让其他实例管理自己的状态.
#要小心继承, 尤其是多重继承. 继承机制有时很有用, 但也会在某些情况下让事情变得过于复杂. 多继承难以正确使用, 更难以调试.
#简单就好. 让你的方法小巧. 一般来说, 多数方法都应能在30秒内读完(以及理解). 尽量将代码行数控制在一页或一屏之内.

#当考虑需要什么类以及类要有什么方法是, 应该尝试下面的方法.
#(1)写下问题的描述(程序要做什么?), 把所有名词, 动词 和 形容词 加下划线
#(2)对于所有名词, 用作可能的类
#(3)对于所有动词, 用作可能的方法
#(4)对于所有形容词, 用作可能的特性
#(5)把所有方法和特性分配到类

#现在已经有了 面向对象模型 的草图了. 还可以考虑类和对象之间的关系(比如继承或协作)以及它们的作用, 可以用以下步骤精炼模型:
#(1) 写下(或者想象)一系列的用例--也就是程序应用时的场景, 试着包括所有的功能
#(2) 一步步考虑每个用例, 保证模型包括所有需要的东西. 如果有些遗漏的话,就添加进来. 如果某处不太正确则修改. 继续, 知道满意为止.

#7.4 小结
# 对象--对象包括特性和方法. 特性只是作为对象的一部分的变量, 方法则是存储在对象内的函数. (绑定的)方法和其他函数的区别在于方法总是将对象
# 作为自己的第一个参数, 这个参数一般称为self.

# 类: 类代表对象的集合(或一类对象), 每个对象(实例)都有(属于)一个类. 类的主要任务是定义它的实例会用到的方法.
# 多态: 多态是实现将不同类型和类的对象进行同样对待的特性--不需要知道对象属于哪个类就能调用方法
# 封装: 对象可以讲它们的内部状态隐藏(或封装)起来. 在一些语言中, 这意味着对象的状态(特性)只对自己的方法可用. 在Python中, 所有的特性
# 都是公开可用的, 但是程序员应该在直接访问对象状态时谨慎行事, 因为他们可能无意中使得这些特性在某些方面不一致.
# 继承: 一个类可以是一个或多个类的子类. 子类从超类继承所有方法. 可以使用多个超类, 这个特性可以用来组成功能的正交部分(没有任何联系). 普通的实现
# 方式是使用核心的超类和一个或多个混合的超类.
# 接口和内省: 一般来说, 对于对象不用探讨过深. 程序员可以靠多态调用自己需要的方法. 不过如果想要知道对象到底有什么方法和特性, 有些函数可以帮助
# 完成这项工作
# 面向对象设计: 完全理解你的问题域,并且创建容易理解的设计是很重要的.

#7.4.1 新函数
# callable		确定对象是否可调用(比如函数或方法)
# getattr(object, name[, default]		确定特性的值, 可选择提供默认值
# hasattr(object, name)		确定对象是否有给定的特性
# isinstance(object, class)		确定对象是否是类的实例
# issubclass(A, B)		确定A是否为B的子类
# random.choice(sequence)		从非空序列中随机选择元素
# setattr(object, name, value)		设定对象的给定特性为value
# type(object)		返回对象的类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值