首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在定义元类时,有没有理由选择__new__而不是__init__?

在定义元类时,选择 __new__ 而不是 __init__ 的原因是:

  1. 元类用于创建类,而不是实例化类。因此,在创建类时,需要使用 __new__ 方法来定义类的创建过程。
  2. __new__ 方法是在类实例化之前被调用的,因此可以用于控制类的创建过程,例如可以在创建类时检查类的定义是否符合规范,或者在创建类时自动添加一些属性或方法等。
  3. __init__ 方法是在类实例化时被调用的,因此不适合用于控制类的创建过程。

以下是一个简单的示例,演示如何使用元类来定义一个类的创建过程:

代码语言:python
代码运行次数:0
复制
class Meta(type):
    def __new__(cls, name, bases, dct):
        # 在创建类之前,可以在这里添加一些属性或方法
        dct['new_attr'] = 'new_value'
        return super().__new__(cls, name, bases, dct)

class MyClass(metaclass=Meta):
    pass

print(MyClass.new_attr)  # 输出:new_value

在这个示例中,我们定义了一个名为 Meta 的元类,并在其中定义了 __new__ 方法。在创建 MyClass 类时,元类 Meta__new__ 方法被调用,并在类的字典中添加了一个名为 new_attr 的属性。最后,我们在 MyClass 类中使用 metaclass 参数指定了元类 Meta,并在 MyClass 类中使用 print 语句输出了 new_attr 属性的值。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

和对象的创建过程(,__new__,__init__,__call__)

__new__方法定义不是必须写的,如果没定义,默认会调用object.__new__去创建一个对象。如果定义了,就是会覆盖,使用自定义的,这样就可以自定制创建对象的行为。  ...处理过程:定义一个,使用声明或者默认的对该类进行创建,对求type运算,得到父(该类声明的的父),调用父的__call__函数,的__call__函数中, 调用该类声明的的..._call__影响的是创建的实例对象的行为,此时如果类自定义了__new__和__init__就可以控制的对象实例的创建和初始化 __new__和__init__ 影响的是创建对象的行为,当这些函数...__call__ 影响()调用行为, __call__是创建的时候调用,即: class Test(object): __metaclass__=type, 定义就是创建,此时会调用的__...call__,如果有继承,子定义执行的是父的__call__。

1.2K50

Python实现Singleton模式的

但是,实际上包裹之后得到的新对象仍然拥有被包裹对象的特性(这句是不是废话:-))。 python中我们经常只需要实现一个装饰器,然后使用该装饰器作用于只能有唯一一个实例的。...可以将my_cls看做是Singleton的一个对象,当我们使用my_cls(...)的方式创建my_cls的对象,实际上是调用Singleton的对象my_cls。...对象可以以函数的方式被调用,那么要求定义__call__函数。不过此处被调用的是,因此我们定义函数__call__来控制my_cls对象创建的唯一性。...参考我之前写的一篇介绍的文章,可知生成对象前会调用函数__new__,如果__new__函数返回被创建的对象,那么会自动调用定义的__init__函数进行对象的初始化操作。...原来的__init__函数已经创建唯一一个对象被调用过。而且只能被调用一次。 这里返回的并不是闭包结构,只是使用装饰器修改了的部分属性,返回的仍是传入的

2K20
  • 每天一道 python 面试题 - Python中的(metaclass) 详细版本

    这就是Python使用关键字class所做的事情,并且通过使用来做到这一点。 什么是(最终) 是创建的“东西”。 您定义是为了创建对象,对吗?...type是Python用于幕后创建所有。 现在,您想知道为什么用小写不是小写Type? 好吧,我想这与str创建字符串对象int的和创建整数对象的的一致性有关。...自定义 的主要目的是创建自动更改它。 通常,您要对API进行此操作,API中要创建与当前上下文匹配的。 想象一个愚蠢的示例,该示例中,您决定模块中的所有的属性都应大写。...它没有什么特别的:__new__始终将其定义作为第一个参数。就像您有self将实例作为第一个参数接收的普通方法一样,还是为方法定义。 但这不是适当的OOP。...我们正在type直接致电,不是覆盖或致电父母的__new__

    42610

    深入理解Python中的(metaclass)

    这就是当你使用关键字classPython幕后做的事情,而这就是通过来实现的。 二、到底什么是(终于到主题了) 就是用来创建的“东西”。你创建就是为了创建的实例对象,不是吗?...type就是Python背后用来创建所有。现在你想知道那为什么type会全部采用小写形式不是Type呢?..._init__之前被调用的特殊方法 # __new__是用来创建对象并返回之的方法 # __init__只是用来将传入的参数初始化给对象 # 你很少用到__new__,除非你希望能够控制对象的创建...# 这里,创建的对象是,我们希望能够自定义它,所以我们这里改写__new__ # 如果你希望的话,你也可以__init__中做些事情 # 还有一些高级的用法会涉及到改写__...但就本身而言,它们其实是很简单的: 1)   拦截的创建 2)   修改 3)   返回修改之后的 五、为什么要用metaclass不是函数?

    42740

    Python中元的概念

    可以理解为是的模板,它定义了一组规则和属性,用于创建新的。当我们通过关键字class定义一个,Python解释器会自动使用来创建该类的对象,并赋予它一些默认的行为和属性。...: MyClass Initializing class: MyClass 可以看到,创建MyClassMyMeta的__new__()方法被调用,并在实例化之前打印了一条消息;接着,__init...和Java的接口以下几个方面有异同: 定义方式:是通过定义特殊的来创建其他Java的接口是通过关键字interface来定义的。...强制性:Java的接口是强制性的,一个必须显式地声明实现某个接口,并且要实现接口中定义的所有方法。Python中是可选的,一个可以选择是否使用来定制自己的行为。...灵活性:由于是动态的,可以的创建过程中进行一些处理,因此相比于Java的接口更加灵活。可以动态地添加、修改或删除的属性和方法,Java的接口一旦定义后就不能再改变。

    19000

    Python每日一题:__new__ 与 __init__

    它也可以用于使用重写,以便我们客制化的创建 首先,我们来看下第一个作用,比如我们有一种需求,是一直要得到大写的字符串,类似新增一种数据类型,它会一直返回字符串的大写形式。...# 调用父 __new__ ,变成大写 return super(UpperStr, cls)....__init__(str.upper(value)) s = UpperStr("abc") print(s) # ABC 其次第二个作用,就是我们通过使用来构造,可以通过重载的 __...new__ 方法,修改 定义 的行为。...这个在后面专题讲 再详细介绍 除了上述作用,__new__ 还可以用于实现单例模式,原理也很简单,就是创建实例对象,先判断是否已经实例化。

    37010

    Python type 和 metaclass

    至于是怎么来的,应用层并不关心,创建这一步就交给处理,而在这一层中做修改,对上层应用来说是透明的。...type 是自己的对象,也是自己的 Python 一切皆对象,要么是 class 的对象,要么是 metaclass 的对象,只有 type 例外。...__new__: 是中,根据入参,创建出普通,即从语法定义生成实体 metaclass 调用 __new__ 创建 class,就像 class 调用 __new__ 创建 object 一样...__init__: __new__ 完成后,即根据语法定义创建出之后调用,给该类做初始化操作 不产生什么返回值 metaclass 调用 __init__ 初始化 class,就像 class 调用...class中定义的 __call__,如object() class以调用方式出现时,就是调用metaclass中定义的 __call__,如class() 这里就是当

    15110

    python 学习-打开潘多拉的魔盒-(metaclass)学习

    __new__() 方法,该方法一定要返回该类的一个实例对象,因为使用创建,该 __new__() 方法会自动被执行,用来修改新建的。...__new__(cls, name, bases, attrs) # 定义一个,指定metaclass 创建,不是由 type 创建 class NewDemo(object, metaclass...当使用class NewDemo 创建,DemoMetaClass 就会触发__init__ 初始化 和 __new__ 创建。...__new__(cls, name, bases, attrs) # 定义一个,指定metaclass 创建,不是由 type 创建 class NewDemo(object, metaclass...学到这大概明白了,是给真正的python 开发者使用的(并不是会写个print 就是python开发者,这里对开发者的定义是能开发框架的开发者),不是给 python 使用者用(python 使用者是会调用第三方库的人员

    22720

    Python笔记:单例实现方法

    另一种简单粗暴的方法是如果确定这一变量必然为某个的操作对象,我们可以将其定义为该类的变量,利用变量先天的唯一性实现全局的操作。...1. python的实例化过程 我们首先来看一下python定义到实例化的完整过程: 变量的实例化以及方法的申明; 的__new__ 的__init__ 的__call__ 本身的...下面就是一些我目前不太理解的问题: python的申明过程中是通过什么机制进行变量的实例化和方法的申明的,这个过程叫做什么? 定义是什么?...根据介入时间点的不同,单例的实现方式大致可以分为以下三种,由前至后分别为: 通过装饰器方式重载的实例化方法 重载的__call__方法 重载的__new__方法 1....self.counter = counter 由于本身的__new__()方法与__init__()方法都是的__call__()函数中进行实现的。

    49830

    Python 基础:与函数

    Refer:http://python.jobbole.com/82308/ 3、Python 中的(下) 3.1 构造和初始化 __new__特性 重写__new__ __init_...文中介绍了的构造和初始化方法:”__new__”和”__init__”。...继承,传入的是哪个实例,就是那个传入的实例,不是定义了self的的实例 描述符中,self指的是描述符的实例 总结: self定义需要定义,但是调用时会自动传入...__属性 自定义 为什么要用metaclass不是函数?...type实际上是它自己的纯Python环境中这可不是你能够做到的,这是通过实现层面耍一些小手段做到的。其次,是很复杂的。对于非常简单的,你可能不希望通过使用来对做修改。

    92890

    什么是metaclass?

    注意:中的__metaclass__属性不会被子类继承,但是父中的__class__会被继承。 自定义 的主要作用是创建的时候自动改变。...,这样模块中所有都会使用该创建 class Foo(): # 注意,新式不支持模块级别的,但是可以定义__metaclass__ bar = 'bip' print(hasattr...# __init__仅用于初始化,进行一些参数的配置 def __new__(upperattr_metaclass, future_class_name,...__new__(cls, clsname, bases, uppercase_attr) 实际上做了以下三方面的工作: 干涉创建的过程 修改 返回修改之后的 为什么使用不是函数来定义?...通常用于处理比较复杂的情况。 可以为__new__、__init__和__call__编写钩子,为后续开发者提供便利。 为什么使用

    39420

    OpenERP与Python 编程

    OpenERP中用到的(MetaClass)作用非常简单:就是V6.1后我们模块中所定义的实体,不需要进行实例化,比如 OpenERPV6.1之前的实体定义: 程序代码: [选择]...__init__(n, 2)     #实例对象初始化 A本身并没有定义__new__方法,所以直接调用其父即:object的__new__方法获得实例对象,如果获得的对象是A的实例则执行__init...,只是就这样登记备案了一下,事实上只有模块载入(loading)过程中才会对所注册的实体实例化,其实也不是一般意义的实例化,而是要另外创造一个新,再做实例化。..._init__两步,的实例化也是一样。...我们看到MetaModel的__init__方法与上面提到的BaseModel的__new__方法中有完全类似的代码: 程序代码: [选择]         if not self.

    74320

    Python学习笔记:单例模式

    实现方式:有两种方式,一种是使用metaclass控制实例化时的对象,另一种是使用的__new__方法控制返回的对象,推荐使用的方式,因为__new__通常是用来改变结构的。...__class__ >>> __call__:当调用一个实例,即执行实例加括号的形式,就会调用该实例的__call__方法,如果没有定义(需要自己定义)...代码执行流程:第一步执行MySingleton(即没加括号的部分),进行的实例化,即MySingleton=Singleton(),Singleton的实例化和普通一样会先执行__new__返回该类的实例...原理:由于每次实例化MySingleton都会先调用metaclass中的__call__方法,所以只有第一次实例化时才会执行MySingleton的__new__和__init__,后面的实例化都只会返回第一次实例化好的实例...缺点:每次实例化虽然都是同一个实例,但是每次实例化都会调用一次__init__方法,导致这个实例会随着每次初始化改变,所以不推荐这种方式来实现单例,因为__new__方法一般是用来改变结构的。

    53130

    Python

    印象中,是创建单例模式知道可以用到(metaclass),但始终对其了解的不是很透彻,很多人也都说是Python中较难理解的概念之一,于是找来几本书,希望可以找到答案,本文以Python3为例...Test() print(id(a)) print(id(b)) 具体的实现是:创建显式的指定的metaclass,定义的metaclass继承type,并重新实现__call__方法。...提出该问题是因为,与Python创建相关的方法是: __new__方法,负责对象的创建,定义需要返回一个实例,我们通过名进行实例化对象自动调用。...如果想要进一步定制,可以中实现__new__方法。 另,编写,通常会把self参数改为cls,这样能更清楚的表明要构建的实例是。...__init__() 执行定义,解释器会先寻找这个类属性中的__metaclass__,如果此属性存在,就将这个属性赋值给此类作为它的,如果此属性没有定义的话,就会向上查找父的__metaclass

    74410

    描述符getsetdelete,initnewcall,

    __call__方法,该方法会在调用对象主要是定义的时候使用时自动触发 class A: pass class B(A): def __new__(cls):...__方法被执行 ''' 我们比较两个方法的参数,可以发现__new__方法是传入(cls),__init__方法传入的实例化对象(self),而有意思的是,__new__方法返回的值就是一个实例化对象...(ps:如果__new__方法返回None,则__init__方法不会被执行,并且返回值只能调用父中的__new__方法,不能调用毫无关系的的__new__方法)。...我们可以这么理解它们之间的关系,__new__是开辟疆域的大将军,__init__是在这片疆域上辛勤劳作的小老百姓,只有__new__执行完后,开辟好疆域后,__init__才能工作。...3. 1.的模板 定义 class 名(type) class Mymeta(type): def __init__(self, class_name, class_bases,

    36020

    再有人问什么是,就把这篇文章扔给他!

    这个是不是很简单很直接,如果需要增加方法,也只是 dict 参数加上对应的方法名即可,如下: ? 我们知道能创建就是,所以说 type 也是一个。...我们还在 metaclass 这个中通过修改__new__这个方法来控制的实现,这时就可以将__init__和__new__这两个方法分离出来了。...这个是我们使用 orm 框架希望是上面这样调用的,这里就简单定义两个字段 name 和 age,User 中还有个内部类是 Meta ,这里面用了定义数据表的其他属性,与字段定义分开,所以里面定义了一个数据表名称...这个基本上是完成了,最后记得调用父的__new__进行返回,要不然会创建对象失败,从而调用不了__init__方法来实例对象。...同时, Model中,我们还需要加上一个判断,只有 User 这个创建才需要控制其的生成,其他的就不需要了。 ? ?

    39820
    领券