__Python中的新初始化

2024-06-28 20:20:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在学习Python,到目前为止,我可以说出下面关于__new____init__的事情:

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

但我现在还有其他问题。

  1. 当我创建一个新实例比如a = MyClass("hello","world")时,如何传递这些参数?我的意思是我应该如何使用__init____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

我没有做更多的实验,因为更远的地方并不明亮,我决定停在那里,并决定问斯塔克弗洛夫。

我读到的SO帖子:

  1. Python object creation
  2. Python's use of __new__ and __init__?

Tags: 对象实例函数名称false类型new参数
1条回答
网友
1楼 · 发布于 2024-06-28 20:20:14

how I should structure the class using __init__ and __new__ as they are different and both accepts arbitrary arguments besides default first argument.

你很少需要担心__new__。通常,您只需定义__init__,并让默认的__new__将构造函数参数传递给它。

self keyword is in terms of name can be changed to something else? But I am wondering cls is in terms of name is subject to change to something else as it is just a parameter name?

两者都只是参数名,在语言中没有特殊意义。但是,在Python社区中,它们的使用是一个非常强的约定;大多数pythonists在这些上下文中永远不会更改名称selfcls,当其他人更改名称时会感到困惑。

请注意,使用def __new__(tuple)重新绑定构造函数内的名称tuple。当实际实现__new__时,您将希望将其作为

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

Albeit I said I want to return tuple, this code works fine and returned me [1,2,3].

MyClass()将具有__new__返回的值。Python中没有隐式类型检查;程序员有责任返回正确的类型(“我们都在这里consenting adults”)。能够返回不同于请求的类型对于实现工厂很有用:您可以返回请求类型的子类。

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

作为参考,请查看Python语言参考中的requirements for ^{}

编辑:好的,下面是一个潜在有用的__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

请注意,有smarter ways可以完成此行为。

相关问题 更多 >