python 类中内置方法的重写

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 类中内置方法的重写相关的知识,希望对你有一定的参考价值。

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

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

class base:
    def __init__(self):
        pass

inspect.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 类中内置方法的重写的主要内容,如果未能解决你的问题,请参考以下文章

python魔法方法

python魔法方法

python -- 类中--内置方法

记一次抽象类中定义的静态变量,多个子类继承后,在方法中被重写引起的问题

python类中内置方法之__call__

python 获取类中除内置方法外的所有方法名