欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python 中的特殊方法,纠正自己笨笨的记忆

程序员文章站 2022-04-09 18:54:21
1. __new__ 和 __init__ 的区别 python 2.x 老式类(默认继承type) 老式类中没有__new__类方法(也就是说定义也不会执行,它不是老式类的类方法),__Init__ 作为构造函数,创建实例对象,并初始化。 过程: 类 => __init__() => 实例(sel ......

1. __new__ 和 __init__ 的区别

  • python 2.x 老式类(默认继承type)
class a:
    pass
    • 老式类中没有__new__类方法(也就是说定义也不会执行,它不是老式类的类方法),__init__ 作为构造函数,创建实例对象,并初始化。
    • 过程: 类 => __init__() => 实例(self)创建并初始化
    • __init__: 不能有返回值
  • python 3 和 python 2.x(显示继承新式类)
class a(object):
    pass

  注: 在python 3.x中没有新式类和老式类之分,它们都继承自'object' 类。因此可以不用显示地指定其基类。'object'基类中拥有的方法和属性可通用于所有的新式类。

    •  __new__ 为类方法,__init__ 为实例方法。__new__ 类方法创建实例对象,__init__ 实例方法初始化实例对象。
    • 过程: 类 => __new__() => 实例对象 => __init__() => 初始化实例
    • __init__ 不能有返回值,__new__ 必须有返回值且 object.__new__(cls) 或 super(类名, cls).__new__(cls),否则__init__ 不执行, object 与 super() 的区别:是否调用父类响应的方法
    • __new__ 的返回值的object.__new__(cls)中不能有多余的参数,比如: super(cls, cls).__new__(cls, *arg, **kwargs) 或 super().__new__(cls, *arg, **kwargs),  *arg, **kwargs 添加应用__init__一致, super() 中的参数要不2个,要不没有
class a(object):
    def __init__(self):
        print "a.__init__ called" # -> is actually never called

    def __new__(cls):
        print "a.__new__ called"
# return super(cls, cls).__new__(cls) # return object.__new__(cls) # 此两种会执行 __init__
    
print a()

2.  __get__, __getattr__, __getattribute__ 的区别

  • 均是访问属性的方法,注意是属性
  • __getattr__(self, name) 当访问属性无法找到时,默认异常,可以自定义其返回值或者 attributeerror 异常
  • __getattribute__(self, name): 2.7 在新式类中引入,如果定义,则无条件执行,如果实行不存在时,也不执行 __getattr__(相当于被屏蔽掉)
  • __get__ (self, instance, owner) : 如果class定义了它,则这个class就可以称为descriptor。owner是所有者的类,instance是访问descriptor的实例,如果不是通过实例访问,而是通过类访问的话,instance则为none。(descriptor的实例自己访问自己是不会触发__get__,而会触发__call__,只有descriptor作为其它类的属性才有意义。)