Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
__Python中的new_uu和_uuinit_uuu_Python_Class - Fatal编程技术网

__Python中的new_uu和_uuinit_uuu

__Python中的new_uu和_uuinit_uuu,python,class,Python,Class,我正在学习Python,到目前为止,我可以讲述以下关于\uuu new\uuu和\uuu init\uuu的内容: \uuuu new\uuuu用于对象创建 \uuuu init\uuuu用于对象初始化 \uuuuuu new\uuuuu在\uuuuu init\uuuuuu作为\uuuuu new\uuuuu返回一个新实例,然后调用\uuuuu init\uuuuuuu,以初始化内部状态 \uuuuu new\uuuuuu适用于不可变对象,因为一旦分配它们,它们就无法更改。因此,我们可以返回具

我正在学习Python,到目前为止,我可以讲述以下关于
\uuu new\uuu
\uuu init\uuu
的内容:

  • \uuuu new\uuuu
    用于对象创建
  • \uuuu init\uuuu
    用于对象初始化
  • \uuuuuu new\uuuuu
    \uuuuu init\uuuuuu
    作为
    \uuuuu new\uuuuu
    返回一个新实例,然后调用
    \uuuuu init\uuuuuuu
    ,以初始化内部状态
  • \uuuuu new\uuuuuu
    适用于不可变对象,因为一旦分配它们,它们就无法更改。因此,我们可以返回具有新状态的新实例
  • 我们可以对这两个可变对象使用
    \uuuuu new\uuuu
    \uuuu init\uuuu
    ,因为它的内部状态可以更改
  • 但我现在还有另外一个问题

  • 当我创建一个新实例,例如
    a=MyClass(“hello”,“world”)
    时,这些参数是如何传递的?我的意思是我应该如何使用
    \uuuu init\uuuu
    \uuu new\uuuuu
    构造类,因为它们是不同的,除了默认的第一个参数之外,它们都接受任意参数
  • self
    关键字的名称是否可以更改为其他名称?但我想知道
    cls
    是在名称方面,还是会更改为其他名称,因为它只是一个参数名称
  • 我做了如下一些小实验:

    >>> class MyClass(tuple):
        def __new__(tuple):
            return [1,2,3]
    
    我做到了以下几点:

    >>> a = MyClass()
    >>> a
    [1, 2, 3]
    
    尽管我说我想返回
    元组
    ,但这段代码运行良好,并返回了我
    [1,2,3]
    。我知道在调用
    \uuuu new\uuuu
    函数后,我们将第一个参数作为我们想要接收的类型进行传递。我们正在谈论新的功能,对吗?除了绑定类型,我不知道其他语言的返回类型

    我还做了其他事情:

    >>> issubclass(MyClass,list)
    False
    >>> issubclass(MyClass,tuple)
    True
    >>> isinstance(a,MyClass)
    False
    >>> isinstance(a,tuple)
    False
    >>> isinstance(a,list)
    True
    
    我没有做更多的实验,因为更远的地方不亮,我决定停在那里,决定问斯塔克

    我看到的这些帖子是:

  • 我应该如何使用
    \uuuu init\uuuu
    \uuu new\uuuuu
    构造类,因为它们是不同的,除了默认的第一个参数外,它们都接受任意参数

    您很少需要担心
    \uuuuu new\uuuuu
    。通常,您只需定义
    \uuuuu init\uuuu
    ,并让默认的
    \uuuu new\uuuuu
    将构造函数参数传递给它

    self
    关键字的名称是否可以更改为其他名称?但我想知道
    cls
    是在名称方面,还是会更改为其他名称,因为它只是一个参数名称

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

    请注意,使用
    def\uuuu new\uuu(tuple)
    在构造函数中重新绑定名称
    tuple
    。在实际实现
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    时,您需要按照以下

    def __new__(cls, *args, **kwargs):
        # do allocation to get an object, say, obj
        return obj
    
    尽管我说我想返回
    元组
    ,但这段代码运行良好,并返回了我
    [1,2,3]

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

    这也解释了您观察到的
    issubclass
    /
    isinstance
    行为:使用
    class MyClass(tuple)
    时会产生子类关系,
    isinstance
    反映了您从
    \uuuuuuuu new\uuuuuu
    返回的“错误”类型

    如需参考,请查看Python语言参考中的

    编辑:好的,下面是一个使用
    \uuuu new\uuuu
    的潜在有用示例。类
    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
    

    请注意,有很多方法可以完成此行为。

    @Braveyard:inherit from
    object
    获取
    \uuuuuuu new\uuuu
    。事实上,除非您正在为非常旧的Python版本编写向后兼容的代码,否则最好始终从
    对象继承。在Python3中,旧样式的类已经消失,而类定义中隐含了从
    对象继承的内容。您不应该从
    \uuuuuuu新的调用
    \uuuuuuuu
    ,如果您返回类型为
    cls
    的实例,Python将自己完成这项工作。我想补充一点,能够从
    \uuuuuu new\uuuuu
    返回某些内容的看似奇怪的行为(至少在理论上)是有用的。我可以想象类似于
    BalancedBinaryTree
    类的东西,它可以从列表中初始化。它有
    LeafNode
    EmptyTree
    的子类,如果输入列表中有0或1个元素,则
    \uuuuuuuuuuu
    返回其中一个。本质上,这意味着您可以实现工厂,而不需要看起来是工厂,因此您可以更改您的类是使用工厂还是直接实例化,而不必破坏您的接口。我认为存在一个bug,它应该是
    类型(self)。n_eels-=1
    ,不
    self.n_-eels-=1
    。在讨论您的鳗鱼示例之前,我给了您+1。希望我能再给你一个