python 类中__init__,__new__,__class__的使用详解

1、python中所有类默认继承object类,而object类提供了很多原始的内置属性和方法,所有用户定义的类在python 中也会继承这些内置属性。我们可以通过dir()进行查看。虽然python提供了很多内置属性但实际开发中常用的不多。而很多系统提供的内置属性实际开发中用户都要重写后才会使用。

class Foo(object):#在python3中object可以不写
    pass
dir(Foo) #查看python中给对象提供的内置属性
***结果****
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__e
at__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init_
ubclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__',
 '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__
shook__', '__weakref__']

2、__init__和__new__的使用

1、__init__方法的使用和功能1、用来构造初始化函数,用来给类的实例进行初始化属性,所以不需要返回值。
    2、在创建实例时系统自动调用
    3、自定义类如果不定义的话,默认调用父类的,同理继承也是,子类若无,调用父类,若有,调用自己的.
   对于第3条举例说明如:
    class A():
    def __init__(self,name):
       self.name=name
    class B(A):
        pass
   obj=B() #对B进行实例
***报错****
 Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'name
    当我们对B进行实例的时候,B本身没有__init__方法,但是父类有,这个时候我们直接通过 obj=B()进行实例 就会报错,所以我们需要给类传入参数obj=B('alex')才能进行实例
2、__new__方法使用和功能1、__new__方法用于给类创建对象,并且返回这个对象。
    2、因为给类创建实例,所以至少传递一个参数cls,参数cls 代表实例化的类,此参数在实例化时由Python解释器自动提供
    3、在类实例化是内部创建实例的函数,并返回这个实例,所以他是实例中最先调用的方法,一般不要认为的定义该方法
    4、创建实例返回实例,所以要有返回值,return父类__new__出来的实例,或者直接是object的__new__出来的实例

class Student(object): #object 在python 3中可以不写
    def __init__(self,name):
        self.name = name
        print("这是__init__方法")
    def __new__(cls,*args,**kwargs):
        print('这是__new_方法')    
        return obj.__new__(cls)
s=Student('tom')
****结果*****结果如下:注意__new__的执行顺序在__init__之前
这是__new__方法
这是_init__方法
3.__init__和__new__使用的联系
  1.__init__第一个参数是self,表示需要初始的实例,由python解释器自动传入,而这个实例就是这个__new__返回的实例
  2.然后 __init__在__new__的基础上可以完成一些其它初始化的动作
 
class Student(object):
    def __init__(self,name):
        self.name = name
        print("这是__init__方法")
 
    def __new__(cls, *args, **kwargs):
        print("这是__new__方法")
        id =object.__new__(cls)
        print(id) #打印这个__new__创建并返回的实例在内存中的地址
        return id
s1 = Student("JACK")
print(s1)
'''
这是__new__方法
<__main__.Student object at 0x000001EC6C8C8748>
这是__init__方法
<__main__.Student object at 0x000001EC6C8C8748>
''' 
总结:很明显,这两个实例的内存地址一样,所以__init__接受的实例就是__new__创建的。

3、__class__的使用:

实例调用__class__属性时指向该实例对应的类,所以_class__功能和type()函数一样,都是查看对象所在的类

class Student(object):
    def __init__(self,name):
        self.name = name
stu = Student("tom")
print(type(stu),type(Student))
print(stu.__class__, Student.__class__, stu.__class__.__class__)
'''结果如下:
<class '__main__.Student'> <class 'type'>
<class '__main__.Student'> <class 'type'> <class 'type'>

4、利用__class__可以找到对象的类,看一道面试题:

class A():
    def show(self):
        print('base show')
class B(A):
    def show(self):
        print('dic show')
如何调用A的show 方法:
obj=B()
obj.show() #对B类实例化,因为B类中有show方法,所以直接用obj.show()调用的是其自身的方法
obj
****结果*****
dic show
<__main__.B object at 0x00000000027EA9E8> #obj是B类的实例化对象
答案:
 obj.__class__=A #__class__ 方法指向了类对象,只用给他赋值类型 A ,然后调用方法 show 
obj.show()
obj
****结果*****
base show
<__main__.A object at 0x00000000027EA9E8> #这时候obj是A类的实例化对象
####注意,由于你对obj对象的类更改,在使用完后要通过 obj.__class__=B进行修改回来,避免后面调用方法错误

猜你喜欢

转载自www.cnblogs.com/dushangguzhousuoli/p/11024067.html