Python 中的 __new__ 和 __init__

2024-03-28

我正在学习 Python,到目前为止我可以讲述以下内容__new__ and __init__:

  1. __new__用于对象创建
  2. __init__用于对象初始化
  3. __new__之前被调用__init__ as __new__返回一个新实例并且__init__之后调用以初始化内部状态。
  4. __new__对于不可变对象很有用,因为它们一旦被分配就无法更改。所以我们可以返回具有新状态的新实例。
  5. 我们可以用__new__ and __init__对于可变对象,因为其内部状态可以更改。

但我现在还有另一个问题。

  1. 当我创建一个新实例时,例如a = MyClass("hello","world"),这些参数是如何传递的?我的意思是我应该如何使用__init__ and __new__因为它们是不同的,并且除了默认的第一个参数之外都接受任意参数。
  2. self关键字是在名称方面可以更改为其他内容吗?但我想知道cls就名称而言,是否可以更改为其他名称,因为它只是参数名称?

我做了如下一些小实验:

>>> class MyClass(tuple):
    def __new__(tuple):
        return [1,2,3]

我做了如下:

>>> a = MyClass()
>>> a
[1, 2, 3]

虽然我说过我想回来tuple,这段代码工作正常并返回给我[1,2,3]。我知道我们正在传递第一个参数作为我们想要接收的类型__new__函数被调用。我们正在谈论New功能对吗?我不知道除了绑定类型之外还有其他语言返回类型吗?

我还做了其他事情:

>>> issubclass(MyClass,list)
False
>>> issubclass(MyClass,tuple)
True
>>> isinstance(a,MyClass)
False
>>> isinstance(a,tuple)
False
>>> isinstance(a,list)
True

我没有做更多的实验,因为进一步的不亮,我决定停在那里并决定询问 StackOverflow。

我读过的SO帖子:

  1. Python 对象创建 https://stackoverflow.com/questions/1164309/python-object-creation
  2. Python 中 __new__ 和 __init__ 的使用? https://stackoverflow.com/questions/674304/pythons-use-of-new-and-init

我应该如何使用来构建类__init__ and __new__因为它们是不同的,并且除了默认的第一个参数之外都接受任意参数。

只有极少数情况下您才需要担心__new__。通常,您只需定义__init__并让默认值__new__将构造函数参数传递给它。

self关键字是在名称方面可以更改为其他内容吗?但我想知道cls就名称而言,是否可以更改为其他名称,因为它只是参数名称?

两者都只是参数名称,在语言中没有特殊含义。但他们的用途是veryPython 社区中的强大约定;大多数 Python 爱好者都会never更改名称self and cls在这些情况下,当其他人这样做时会感到困惑。

请注意,您使用def __new__(tuple)重新绑定名称tuple构造函数内部。实际实施时__new__,你会想要这样做

def __new__(cls, *args, **kwargs):
    # do allocation to get an object, say, obj
    return obj

虽然我说过我想回来tuple,这段代码工作正常并返回给我[1,2,3].

MyClass()将具有以下价值__new__返回。 Python 中没有隐式类型检查;返回正确的类型是程序员的责任(“我们都是同意的成年人 http://mail.python.org/pipermail/tutor/2003-October/025932.html此处“)。能够返回与请求不同的类型对于实现工厂很有用:您可以返回请求类型的子类。

这也解释了issubclass/isinstance您观察到的行为:子类关系来自您的使用class MyClass(tuple), the isinstance反映您从返回“错误”类型__new__.

作为参考,请查看要求__new__ http://docs.python.org/reference/datamodel.html#object.__new__ in the Python 语言参考.

Edit:好的,这是一个可能有用的示例__new__。班上Eel跟踪在此过程中有多少条鳗鱼还活着,如果超过某个最大值,则拒绝分配。

class Eel(object):
    MAX_EELS = 20
    n_eels = 0

    def __new__(cls, *args, **kwargs):
        if cls.n_eels == cls.MAX_EELS:
            raise HovercraftFull()

        obj = super(Eel, cls).__new__(cls)
        cls.n_eels += 1
        return obj

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

    def __del__(self):
        type(self).n_eels -= 1

    def electric(self):
        """Is this an electric eel?"""
        return self.voltage > 0

请注意,有更聪明的方法 https://stackoverflow.com/questions/674304/pythons-use-of-new-and-init/674345#674345来完成这个行为。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 中的 __new__ 和 __init__ 的相关文章

随机推荐

  • fscanf 无法正确读取浮点数

    这是一个家庭作业问题 我在使用 fscanf 从文本文件读取浮点值时遇到问题 基本上我试图从文件中读取浮点值并将它们存储在动态数组中 输入文件每行有两个浮点数 所以一行可能是 0 85 7 34 不带引号 所以我尝试使用 fscanf fp
  • 如何使用flask-ReSTplus记录帖子正文?

    如何记录预期发布的输入正文value字段出现以便用户知道要发布什么 目前使用以下数据 customer id service id customer name site name service type 我们可以使用上面的 json 来默
  • 将同步代码包装为异步任务的最佳方法是什么?

    我正在实现一个异步接口方法 返回任务 然而 我的实现必然是同步的 最好的方法是什么 有一些内置的方法可以做到这一点吗 以下是我正在考虑的几个选项 选项 1 Task FromResult return Task FromResult Com
  • 如何轮询目录以检查是否添加了新文件?

    我想轮询一个目录以检查是否有新文件添加到该目录中 如果添加了任何新文件 我想读取该文件 有人可以告诉我如何做到这一点吗 Java 7 有一个文件观察器API http java dzone com news how watch file s
  • 将 datetimeoffset 数据类型与 jTDS 结合使用

    jTDS 目前不支持datetimeoffsetSQL Server 2008 中引入的数据类型 任何人都可以建议是否有办法使用datetimeoffset使用 jTDS 键入 正如在 下层客户端的向后兼容性 部分中提到的日期时间偏移文档
  • Protobuf.net“一旦生成序列化器,就无法更改类型”

    我有一些使用 Protobuf net 的相当简单的代码 它抛出了一个非常奇怪的异常 在 MetaType cs 的第 167 行中 它抛出 InvalidOperationException 一旦生成序列化程序 就无法更改类型 这是什么意
  • 单击按钮时切换弹出模式

    我在页面上显示包含多个项目的弹出窗口时遇到问题 本质上 它是页面下方项目的垂直 列表 到目前为止我有两个 当我单击第一个项目时 第一组信息会正确显示 但是当我单击第二个项目时 它会在弹出窗口中显示第一组信息 任何帮助表示赞赏 谢谢 docu
  • AVFoundation 点击​​聚焦反馈矩形

    我正在开发一个 iPhone 应用程序 我直接使用 AVFoundation 通过相机捕获视频 我已经实现了一项功能来启用tap to focus为用户提供的功能 void focus CGPoint aPoint if HAS AVFF
  • 使用 webpack 和 React 模块解析失败,即使使用 babel-loader

    我正在尝试将 webpack 与 React 一起使用 但收到此错误 app main js 中出现错误 Module parse failed Users me app main js Line 2 Unexpected token Yo
  • gcc 警告:标量初始值设定项周围有大括号

    我有如下定义的查找表 并且正在使用 GCC 当我编译时 我收到警告 warning braces around scalar initializer 这个警告是什么意思 我应该如何初始化这个LUT 我在初始化这个结构时犯了错误吗 Help
  • 如何在 Google Colaboratory 的 Jupyter Notebook 中安装 svmutil?

    我想使用 svmutil 函数https github com Netflix vmaf tree master libsvm python https github com Netflix vmaf tree master libsvm
  • 为整个 iOS 应用程序快速使用自定义字体

    我知道要在屏幕上设置元素的自定义字体我可以简单地执行以下操作someLabel font UIFont name Exo 2 0 size 15 我想知道如何使用 swift 为整个应用程序设置它 一种黑客方法是对应用程序的每个元素执行我所
  • FLTK简单动画

    我可以成功编译并运行 Hello World 代码 现在我想做一些像动画这样的事情 我首先创建一个矩形类来实现 Fl widget 中的 draw class myRect public Fl Widget private Fl Color
  • 有没有一种简单的方法将 C++ 枚举转换为字符串?

    假设我们有一些命名枚举 enum MyEnum FOO BAR 0x50 我在谷歌上搜索的是一个脚本 任何语言 它扫描我的项目中的所有标头并生成每个枚举具有一个函数的标头 char enum to string MyEnum t 以及类似这
  • 如何使引导图标与标签中的文本内联显示?

    我有显示文本和箭头的引导导航药丸 不幸的是 如果文本太长 箭头就会出现在锚点的边框上 Html 看起来像这样 a href span Some longer sample text span i class pull right icon
  • Pandas 根据有时相反的两列删除重复项

    我有一个 DF 看起来像 c1 c2 c3 1 A B x 2 A C y 3 B A x 4 B D z 5 A B y 正如你所看到的 如果我们忽略这一点 第 1 行和第 3 行就会重复c1 and c2是不同的列 或者如果它们颠倒了
  • 如何避免 Go 中的初始化循环

    当我尝试编译这段代码时 package main import encoding json fmt net http func main fmt Println Hello playground const GET GET POST POS
  • 如何为表达式添加括号?

    我有一个想法 可以制作一个简单的程序 它将帮助我处理 C 等语言中的运算符优先级 其中最困难的部分是为表达式加上括号 例如 我想要这个 a x b x 转换成这样 a x b x 我在以下步骤中手动完成 a x b x a x b x a
  • PowerShell 类方法的引用参数? [参考][Uint64]

    我有一个 powershell 类 我需要传递对 UInt64 变量的引用并从方法返回一个值 我正在尝试执行类似于下面代码的操作 但它给了我一个语法错误 也许我不需要添加 参考 因为所有变量在 powershell 中默认都是引用 包括 u
  • Python 中的 __new__ 和 __init__

    我正在学习 Python 到目前为止我可以讲述以下内容 new and init new 用于对象创建 init 用于对象初始化 new 之前被调用 init as new 返回一个新实例并且 init 之后调用以初始化内部状态 new 对