开始Python -- Magic方法(1)

1、构造函数

1 __init__

l         要为类提供构造函数,只要在类中实现__init__()方法:

class FooBar:

         def __init__(self):

                 self.somevar = 42

 

>>> f = FooBar()

>>> f.somevar

42

l         可以为构造函数提供参数:

class FooBar:

         def __init__(self, value=42):

                 self.somevar = value

 

>>> f = FooBar('This is a constructor argument')

>>> f.somevar

'This is a constructor argument'

l         重载构造函数的例子:

class Bird:

         def __init__(self):

                 self.hungry = 1

         def eat(self):

                 if self.hungry:

                                   print 'Aaaah...'

                                   self.hungry = 0

                 else:

                                   print 'No, thanks!'

 

class SongBird(Bird):

         def __init__(self):

                 self.sound = 'Squawk!'

         def sing(self):

                 print self.sound

l         由于重载构造函数时没有调用父类的构造函数,所以执行下面语句会抛异常:

>>> sb = SongBird()

>>> sb.sing()

Squawk!

>>> sb.eat()

Traceback (most recent call last):

  File "<interactive input>", line 1, in ?

  File "D:/workshop/src/python/bird.py", line 5, in eat

    if self.hungry:

AttributeError: SongBird instance has no attribute 'hungry'

2)调用非绑定的父类构造函数

l         在子类的构造函数调用supperclass._init__(),由于是非绑定的,需要传递self

class SongBird(Bird):

         def __init__(self):

                 Bird.__init__(self)

                 self.sound = 'Squawk!'

         def sing(self):

                 print self.sound

l         这样就能正常调用eat()方法:

>>> sb = SongBird()

>>> sb.sing()

Squawk!

>>> sb.eat()

Aaaah...

3) 使用supper()函数

l         supper()只能在new-style类中使用:基类必须继承object

l         调用supper()时,将当前的类和实例作为参数传递,调用__init__()时不需要传递self

class Bird(object):

         def __init__(self):

                 self.hungry = 1

         def eat(self):

                 if self.hungry:

                                   print 'Aaaah...'

                                   self.hungry = 0

                 else:

                                   print 'No, thanks!'

 

class SongBird(Bird):

         def __init__(self):

                 super(SongBird, self).__init__()

                 self.sound = 'Squawk!'

         def sing(self):

                 print self.sound

l         使用supper()函数要比调用非绑定的父类构造函数更好,特别是多重继承时,只需要调用一次就行了

 

2、项目访问

l         为了使自己创建的类具有SequenceMapping的基本功能,可以实现下面的Magic方法:

Ø         __len__(self):返回项目的数目,对于Sequence是元素个数,对于Mappingkey/value对的个数

Ø         __getitem__(self, key):根据key返回值,对于Sequencekey0~n-1nSequence的长度,可以为负数),对于Mappingkey可以是任意值

Ø         __setitem__(self, key, value):保存值valuekey指定的地方(对可变对象可用)

Ø         __delitem__(self, key):根据key删除值(对可变对象可用)

l         下面是一个实现的例子:

def checkIndex(key):

    """

    Is the given key an acceptable index?

    To be acceptable, the key should be a non-negative integer. If it

    is not an integer, a TypeError is raised; if it is negative, an

    IndexError is raised (since the sequence is of infinite length).

    """

    if not isinstance(key, (int, long)): raise TypeError

    if key<0: raise IndexError

   

class ArithmeticSequence(object):

    def __init__(self, start=0, step=1):

        """

        Initialize the arithmetic sequence.

        start - the first value in the sequence

        step - the difference between two adjacent values

        changed - a dictionary of values that have been modified by

        the user

        """

        self.start = start # Store the start value

        self.step = step # Store the step value

        self.changed = {} # No items have been modified

       

    def __getitem__(self, key):

        """

        Get an item from the arithmetic sequence.

        """

        checkIndex(key)

        try: return self.changed[key] # Modified?

        except KeyError: # otherwise...

            return self.start + key*self.step # ...calculate the value

   

    def __setitem__(self, key, value):

        """

        Change an item in the arithmetic sequence.

        """

        checkIndex(key)

        self.changed[key] = value # Store the changed value

l         下面是调用的一些例子,由于没有实现__delitem__(),所以del操作会抛异常:

>>> s = ArithmeticSequence(1, 2)

>>> s[4]

9

>>> s[4] = 2

>>> s[4]

2

>>> del s[4]

Traceback (most recent call last):

  File "<interactive input>", line 1, in ?

AttributeError: __delitem__

 

3、继承内建类

l         上面为实现内建类具有的功能,需要逐个实现方法,其实可以直接继承这些内建的类,重载需要调整功能的方法:

class CounterList(list):

    def __init__(self, *args):

        super(CounterList, self).__init__(*args)

        self.counter = 0

    def __getitem__(self, index):

        self.counter += 1

        return super(CounterList, self).__getitem__(index)

l         下面是调用的一些例子:

>>> cl = CounterList(range(10))

>>> cl

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> del cl[3:6]

>>> cl.counter

0

>>> cl[4] + cl[2]

9

>>> cl.counter

2

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值