【python】-- 类的创建、__new__、__metaclass___

类的创建

前面的随笔都是关于类的知识,通过类创建对象,那这个类到底是怎么产生的呢?

1、 传统创建类

class Foo(object):
    def __init__(self,name):
        self.name = name

f = Foo("shuaigaogao")

  

f 是通过 Foo 类实例化的对象,其实,不仅 f 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象,按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。

print(type(f))    #输出:<class ‘__main__.Foo‘>  表示:f 对象由Foo类创建
print(type(Foo))  #输出:<class ‘type‘>          表示:Foo类对象由 type 类创建

所以,f对象是Foo类的一个实例Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建

2 、type创建类

说明:  type创建类的格式,类名 = type(‘类名‘,(父类,),{‘方法名‘:方法的内存地址})

def func(self):  #创建方法
    print("hello {0}".format(self.name))

def __init__(self,name):  #创建构造方法
    self.name = name

#通过type创建类,如果是经典类的话则写成:Foo = type("Foo",(),{"talk":func,"__init__":__init__})
Foo = type("Foo",(object,),{"talk":func,"__init__":__init__})
f = Foo("shuaigaogao")  #创建对象
f.talk()

#输出
hello shuaigaogao  

总结:类 是由 type 类 实例化产生的

值得注意的是,新式类的写法,在继承父类那边,你继承一个父类后面就要加一个逗号,加逗号,它就把它当做一个元组,不加逗号,就是一个值了

__new__方法

1 、概念

new方法是类自带的一个方法,可以重构,__new__方法在实例化的时候也会执行,并且先于__init__方法之前执行

class Foo(object):

    def __init__(self,name):
        self.name = name

        print("Foo __init__")

    def __new__(cls, *args, **kwargs):
        print("Foo __new__",cls, *args, **kwargs)
        return object.__new__(cls)

f = Foo("shuaigaogao")

#输出
Foo __new__ <class ‘__main__.Foo‘> shuaigaogao  #执行了new方法
Foo __init__  #执行了__init__方法

  

2、 new方法作用

作用:所有对象都是通过new方法来实例化的,new里面调用了init方法,所以在实例化的过程中先执行的是new方法,而不是init方法。

①重构__new__方法

class Foo(object):

    def __init__(self,name):
        self.name = name
        print("Foo __init__")

    def __new__(cls, *args, **kwargs):
        print("Foo __new__",cls, *args, **kwargs)

f = Foo("shuaigaogao")  #实例化

#输出
Foo __new__ <class ‘__main__.Foo‘> shuaigaogao

由上面的例子看出,没有执行__init__方法

②重构__new__方法,并继承父类的__new__方法

class Foo(object):

    def __init__(self,name):
        self.name = name

        print("Foo __init__")

    def __new__(cls, *args, **kwargs):   #cls相当于传入类Foo
        print("Foo __new__",cls, *args, **kwargs)
        return object.__new__(cls)  #继承父类的__new__方法,这边必须以返回值的形式继承

f = Foo("shuaigaogao")

#输出
Foo __new__ <class ‘__main__.Foo‘> shuaigaogao

由上面不难看出,大多数情况下,你都不要去重构你的__new__方法,因为你父类中已经有__new__方法了,已经帮你写好了怎么去创建类,如果你重写的话,就会覆盖父类的里面的__new__方法。但是你重构可以增加一点小功能,但是你覆盖了以后还是需要继承父类回来,要不然你的这个实力就创建不了。

3、使用场景

我想对我自己写的一些类进行定制,就在它实例化之前就进行定制,就可以用到__new__方法,new方法就是用来创建实力的,重构new方法,必须以返回值的形式继承父类的new方法。

①需求:我在创建对象时候,同时创建一个类变量

class Foo(object):

    def __init__(self,name):
        self.name = name

        print("Foo __init__")

    def __new__(cls, *args, **kwargs):  #cls相当于是传入的类名Foo
        cls.name = "shuaigaogao"  #创建对象是定义静态变量
        print(cls.name)
        return object.__new__(cls)  #继承父类的__new__方法

f = Foo("shuaigaogao")
print(Foo.name)

#输出
shuaigaogao
Foo __init__
shuaigaogao

__metaclass__方法

metaclass这个属性叫做元类,它是用来表示这个类是由谁来帮他实例化创建的,说白了,就是相当于自己定制一个类。

class MyType(type):
    def __init__(self,*args,**kwargs):

        print("Mytype __init__",*args,**kwargs)

    def __call__(self, *args, **kwargs):
        print("Mytype __call__", *args, **kwargs)
        obj = self.__new__(self)
        print("obj ",obj,*args, **kwargs)
        print(self)
        self.__init__(obj,*args, **kwargs)
        return obj

    def __new__(cls, *args, **kwargs):
        print("Mytype __new__",*args,**kwargs)
        return type.__new__(cls, *args, **kwargs)

class Foo(object,metaclass=MyType):  #python3统一用这种
    #__metaclass__ = MyType  #python2.7中的写法

    def __init__(self,name):
        self.name = name

        print("Foo __init__")

    def __new__(cls, *args, **kwargs):
        print("Foo __new__",cls, *args, **kwargs)
        return object.__new__(cls)

f = Foo("shuaigaogao")
print("f",f)
print("fname",f.name)

#输出
Mytype __new__ Foo (<class ‘object‘>,) {‘__new__‘: <function Foo.__new__ at 0x0000025EF0EFD6A8>,
‘__init__‘: <function Foo.__init__ at 0x0000025EF0EFD620>, ‘__qualname__‘: ‘Foo‘, ‘__module__‘: ‘__main__‘}
Mytype __init__ Foo (<class ‘object‘>,) {‘__new__‘: <function Foo.__new__ at 0x0000025EF0EFD6A8>,
 ‘__init__‘: <function Foo.__init__ at 0x0000025EF0EFD620>, ‘__qualname__‘: ‘Foo‘, ‘__module__‘: ‘__main__‘}
Mytype __call__ shuaigaogao
Foo __new__ <class ‘__main__.Foo‘>
obj  <__main__.Foo object at 0x0000025EF0F05048> shuaigaogao
<class ‘__main__.Foo‘>
Foo __init__
f <__main__.Foo object at 0x0000025EF0F05048>
fname shuaigaogao

创建过程如下:

更多__metaclass__知识:点击

总结:

  类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__

时间: 2024-08-27 21:29:18

【python】-- 类的创建、__new__、__metaclass___的相关文章

Python类的创建过程

类的创建过程 以下说的类指的类本身,例如以下代码: class Foo: def __init__(self): pass 则指的 Foo 的创建过程,而不是 Foo 的实例. 1. 解析 MRO 记录(Resolving MRO entries) 根据 MRO 规则解析继承关系 2. 确定元类(Determining the appropriate metaclass) 查找元类的过程遵循以下规则: 如果没有基类且没有指定 metaclass ,则使用 type() 如果指定了 metacla

python 类的创建、实例化、构造函数、私有属性

例子: #!/usr/bin/env python class people:         def __init__(self,name):                 self.name = name         def __sayHi(self):                 print 'How do you do!'         def printname(self):                 print 'Hi,%s' % self.name        

python 类的创建和使用

原文:https://www.runoob.com/python3/python3-class.html 原文:https://www.cnblogs.com/danhuai/p/11731319.html class MyClass: """一个简单的类实例""" i = 12345 def f(self): return 'hello world' # 实例化类 x = MyClass() # 访问类的属性和方法 print("My

Python类的__new__()

本篇主要想要详细的介绍一下关于类的魔法方法__new__()方法. 在学习之前我们看一下Python3中关于object基类的__new__() 方法: @staticmethod # known case of __new__ def __new__(cls, *more): # known special case of object.__new__ """ Create and return a new object. See help(type) for accura

Python中动态创建类实例

Python中动态创建类实例 简介 在Java中我们可以通过反射来根据类名创建类实例,那么在Python我们怎么实现类似功能呢? 其实在Python有一个builtin函数import,我们可以使用这个函数来在运行时动态加载一些模块.如下: def createInstance(module_name, class_name, *args, **kwargs): module_meta = __import__(module_name, globals(), locals(), [class_n

python3 速查参考- python基础 8 -&gt; 面向对象基础:类的创建与基础使用,类属性,property、类方法、静态方法、常用知识点概念(封装、继承等等见下一章)

基础概念 1.速查笔记: #-- 最普通的类 class C1(C2, C3): spam = 42 # 数据属性 def __init__(self, name): # 函数属性:构造函数 self.name = name def __del__(self): # 函数属性:析构函数 print("goodbey ", self.name) I1 = C1('bob') #-- Python的类没有基于参数的函数重载 class FirstClass: def test(self,

Python 【类的创建和类的实例化】

一.类的创建 #类的实例化 class Dog(object):#object类,o小写 type = "宠物" #类变量 def __init__(self,name,age): #初始化方法 self.name = name #实例变量(属性) self.age = age self.run() def run(self): #普通方法 print(self.name,"在咆哮!") def eat(self,speed): print(self.name,&q

python类和对象的底层实现

按照python中"一切皆对象的原理",所有创建的对象,都是一个已知存在的class实例化的结果;那么class又是被哪个"类"实例化的呢?先看下面的一段代码 class Foo(object): pass obj = Foo() print type(obj) print type(Foo) 结果为: <class '__main__.Foo'> <type 'type'> 可以看到:obj是由Foo实例化,而Foo由type类创建 这样F

python 类的特殊成员方法

__doc__ # 输出类的描述信息 __module__ # 表示当前操作的对象在那个模块 __class__ # 表示当前操作的对象的类是什么 __init__ # 构造方法,通过类创建对象是,自动触发执行. __del__ # 构造方法,当对象在内存中释放是,自动触发执行. __call__ # 对象后面加括号,触发执行 注:构造方法的执行是由创建对象触发的,即:对象 = 类名();而对于__call__方法的执行是由对象后加括号触发的,即:对象()或者类()() __dict__ # 查