开始Python -- 抽象化(2)

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 0x 0100C 3B0>, '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 0x 0100A 960>, <class __main__.Talker at 0x0100AA80>)

>>> s.__class__

<class __main__.SPAMFilter at 0x 0100A 660>

 

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}

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值