您的位置:首页 > 编程语言 > Python开发

开始Python -- 抽象化(2)

2007-10-18 17:52 295 查看
4、创建自己的类
l 类是一种类型的对象的抽象,而对象是属于类的实例
l 使用class关键字创建类:

>>> 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
...

l 类中定义的方法(确切的称为绑定方法)会将第一个参数绑定到属于这个类的实例,所以在调用方法时,不需要提供该参数:

>>> foo = Person()
>>> foo.setName('Luke Skywalker')
>>> foo.greet()
Hello, world! I'm Luke Skywalker.

l 在调用setName()方法后,foo对象就有了新创建的name属性(之前是不存在的),可以直接访问:

>>> foo.name
'Luke Skywalker'
>>> foo.name = 'Yoda'
>>> foo.greet()
Hello, world! I'm Yoda.

l 和函数一样,可以使用变量指向方法:

>>> greet = foo.greet
>>> greet()
Hello, world! I'm Yoda.

(1) 类Namespace:类成员可访问的范围

>>> class MemberCounter:
... members = 0
... def init(self):
... MemberCounter.members += 1
...

l 上面的例子中,members被定义成类范围的变量(类似Java中的static变量),所以可以被所有成员(这里指实例)访问:

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

l 同样,实例可以直接访问类变量:

>>> m1.members
2
>>> m2.members
2

l 但是对members赋值不会改变类变量的值,因为这会在实例范围中创建新的变量:

>>> m1.members = 'Two'
>>> m1.members
'Two'
>>> m2.members
2
>>> vars(MemberCounter)
{'__module__': '__main__', 'init': <function init at 0x0100C3B0>, 'members': 2, '__doc__': None}
>>> vars(m1)
{'members': 'Two'}

(2) 私有化(private)
l Python不直接支持私有化机制,类中方法和属性都是公有的,但可以通过在方法或属性前加“__”(2个下划线)实现私有化:

>>> 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 "<interactive input>", line 1, in ?
AttributeError: Secretive instance has no attribute '__inaccessible'
>>> s.accessible()
The secret message is:
Bet you can't see me...

l 其原理是:Python会将2个下划线转换成“_classname”的形式,因此还是可以访问类的私有方法:

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

5、继承
l 在类名后用“()”将父类名括起:

>>> 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 a subclass of Filter
... def init(self): # Overrides init method from Filter superclass
... self.blocked = ['SPAM']
...
>>> s = SPAMFilter()
>>> s.init()
>>> s.filter(['SPAM', 'SPAM', 'SPAM', 'SPAM', 'eggs', 'bacon', 'SPAM'])
['eggs', 'bacon']

l 允许多重继承:

>>> 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

l 要注意的是如果父类中有同名的方法,则前面父类的方法会重载后面父类的方法
(1) 关于继承的函数和全局属性
l isinstance:检查指定对象是否是指定类的实例
l issubclass:检查指定类是否是指定类的子类
l __bases__:获得指定类的父类
l __class__:获得指定对象的类

>>> isinstance(s, SPAMFilter)
True
>>> issubclass(SPAMFilter, Filter)
True
>>> SPAMFilter.__bases__
(<class __main__.Filter at 0x0100AA50>,)
>>> TalkingCalculator.__bases__
(<class __main__.Calculator at 0x0100A960>, <class __main__.Talker at 0x0100AA80>)
>>> s.__class__
<class __main__.SPAMFilter at 0x0100A660>

6、接口
l Python不同于Java,不需要显式的定义接口,只要要求对象实现指定的方法就可以了
l 下面是一些检查属性的函数和全局属性:
Ø hasattr:需要的方法是否存在
Ø getattr:获得指定的方法或属性,不存在则使用缺省值
Ø setattr:设置指定的属性,如果不存在则新建
Ø callable:指定属性是否可调用(方法)
Ø __dict__:获得属性Dictionary

>>> hasattr(tc, 'talk')
True
>>> callable(getattr(tc, 'talk', None))
True
>>> setattr(tc, 'name', 'Mr. Gumby')
>>> tc.name
'Mr. Gumby'
>>> tc.__dict__
{'name': 'Mr. Gumby', 'value': 7}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: