《Beginning Python From Novice to Professional》学习笔记十一:__Magic__

时间:2021-09-10 05:46:01
n大魔力

1.构造函数
   
f = FooBar('This is a constructor argument')
f.somevar   --->
'This is a constructor argument'

在继承机制中调用父类的构造函数
①调用父类的类构造函数(Unbound)
    
 

          
②使用super函数
super函数相当智能,尤其在多重继承的情况下。

本书作者对这两种方法的一种总结:You don’t have to understand exactly how it works internally, but you should be aware that, in most cases, it is clearly superior to calling the unbound constructors (or other methods) of your superclasses.

2.基本Sequence和Mapping协议(Protocol)
关于Protocol的说明:Where other languages might require an object to belong to a certain class, or to implement a certain interface, Python often simply requires it to follow some given protocol. 我的理解是要使得对象具有某种Builtin对象的性质所必须的一种规范。

__len__(self):
在Sequence中返回元素的个数,在Mapping中返回key-value对的个数。如果__len__返回zero(前提是未实现__nonzero__),则此对象会被当做Boolean值的false(与空 lists, tuples, strings, dictionaries相同)。
__getitem__(self, key):
返回与key相应的值,Sequence中key为0到n-1(也可以为负,后述),Mapping中为实际的key
__setitem__(self, key, value):
只能在可写对象中使用
__delitem__(self, key):

以上四个Protocols的几点说明:
①如果Sequence中的key为负数,则为从后倒数,如x[-n] = x[len(x)-n]
②如果key的类型不对,如在Sequence中使用String为key,会引发TypeError异常
③如果Sequence的key的类型对,但是越界,会引发IndexError异常

一个自定义Sequence的例子:
 
  
下面是对此类的使用:
s = ArithmeticSequence(1, 2)
s[4]   ---> 9
s[4] = 2
s[4]   ---> 2
s[5]   ---> 11
其行为像Sequence,可以使用[]操作符,类似于C++中的Operator重载。

# ArithmeticSequence类没有定义__delitem__,所以del s[4]这样的行为会引起异常。
# s["four"]会引起TypeError
# s[-42]会引起IndexError
# 类中未定义 __len__ ,因为这是个无限长的Sequence。


## 在制作这种类似于Builtin类的时候要注意一点就是尽量遵从标准,比如这里就尽管用的是{}Dictionary,但还是用isinstance(key, (int, long))来检查key是否为整数,因为Builtin的key只能是整数。

如果从标准库继承类(这种类叫 UserList, UserString, UserDict),则不需要自己写所有的方法,只要重写自己需要的方法:

#在这里就可以直接使用list中的 append, extend, index等等函数,以下为使用:
cl = CounterList(range(10))
cl   ---> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
cl.reverse()
cl   ---> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
del cl[3:6]
cl   ---> [9, 8, 7, 3, 2, 1, 0]
cl.counter   ---> 0
cl[4] + cl[2]   ---> 9
cl.counter   ---> 2