python 类中内置方法的重写,,为达成目的,经常会在


为达成目的,经常会在类中将一些内置方法进行重写,最常见的例如__setattr__,下面就通过内置属性,来查看重写会带来什么变化

先定义一个测试用的类,代码如下

class base:    def __init__(self):        passinspect.getmembers(base): # 查看内置属性

打印结果如下

技术分享
(‘__class__‘, <class ‘type‘>)(‘__delattr__‘, <slot wrapper ‘__delattr__‘ of ‘object‘ objects>)(‘__dict__‘, mappingproxy({‘__module__‘: ‘__main__‘, ‘__init__‘: <function base.__init__ at 0x0069A0C0>, ‘__getattr__‘: <function base.__getattr__ at 0x0069A108>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘base‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘base‘ objects>, ‘__doc__‘: None}))(‘__dir__‘, <method ‘__dir__‘ of ‘object‘ objects>)(‘__doc__‘, None)(‘__eq__‘, <slot wrapper ‘__eq__‘ of ‘object‘ objects>)(‘__format__‘, <method ‘__format__‘ of ‘object‘ objects>)(‘__ge__‘, <slot wrapper ‘__ge__‘ of ‘object‘ objects>)(‘__getattr__‘, <function base.__getattr__ at 0x0069A108>)(‘__getattribute__‘, <slot wrapper ‘__getattribute__‘ of ‘object‘ objects>)(‘__gt__‘, <slot wrapper ‘__gt__‘ of ‘object‘ objects>)(‘__hash__‘, <slot wrapper ‘__hash__‘ of ‘object‘ objects>)(‘__init__‘, <function base.__init__ at 0x0069A0C0>)(‘__init_subclass__‘, <built-in method __init_subclass__ of type object at 0x00699030>)(‘__le__‘, <slot wrapper ‘__le__‘ of ‘object‘ objects>)(‘__lt__‘, <slot wrapper ‘__lt__‘ of ‘object‘ objects>)(‘__module__‘, ‘__main__‘)(‘__ne__‘, <slot wrapper ‘__ne__‘ of ‘object‘ objects>)(‘__new__‘, <built-in method __new__ of type object at 0x1E1FADB8>)(‘__reduce__‘, <method ‘__reduce__‘ of ‘object‘ objects>)(‘__reduce_ex__‘, <method ‘__reduce_ex__‘ of ‘object‘ objects>)(‘__repr__‘, <slot wrapper ‘__repr__‘ of ‘object‘ objects>)(‘__setattr__‘, <slot wrapper ‘__setattr__‘ of ‘object‘ objects>)(‘__sizeof__‘, <method ‘__sizeof__‘ of ‘object‘ objects>)(‘__str__‘, <slot wrapper ‘__str__‘ of ‘object‘ objects>)(‘__subclasshook__‘, <built-in method __subclasshook__ of type object at 0x00699030>)(‘__weakref__‘, <attribute ‘__weakref__‘ of ‘base‘ objects>)
base的内置属性

找到__setattr__,发现他是一个 slot wrapper(是否可以理解为插口包装)

‘__setattr__‘, <slot wrapper ‘__setattr__‘ of ‘object‘ objects>

对__setattr__进行重写,在赋值的时候打印key与value

def __setattr__(self , key , value):    print(key,value)    self.__dict__[key] = value

再次打印,发现__setattr__变为了普通的方法

(‘__setattr__‘, <function base.__setattr__ at 0x0227F108>)

总结:在重写内置方法时,内置方法会从slot wrapper变为普通的function,slot wrapper-->function

----------------------------------------------------------------分割线----------------------------------------------------------------

疑问:如果有类继承,父类重写,子类是否也继承?

技术分享
 1 class base: # 父类 2     def __init__(self): 3         pass 4  5     def __setattr__(self, key, value): 6         print(key, value) 7         self.__dict__[key] = value 8  9 class Foo(base): # 子类10     def __init__(self):11         pass
子类Foo未重写方法

情况1: 子类Foo未重写__setattr__,父类base与子类Foo的内置属性中,__setattr__完全相同

# 父类base(‘__setattr__‘, <function base.__setattr__ at 0x0243E108>)# 子类Foo(‘__setattr__‘, <function base.__setattr__ at 0x0243E108>)

情况2,子类Foo重写__setattr__方法,二者不同

# 父类base(‘__setattr__‘, <function base.__setattr__ at 0x0243E108>)# 子类Foo(‘__setattr__‘, <function Foo.__setattr__ at 0x022BE198>)

,总结:在有继承关系时, 1:父类重写内置方法会影响到所有的子类

            2:子类将方法重写后与继承特性相同,会覆盖父类的相同的方法

            3:在多重继承中,如果父类都重写了该方法,则会继承写在前面的那个父类的方法(具体请参考我的另一片关于多重继承的文章)

python 类中内置方法的重写

评论关闭