简体   繁体   English

在python中继承元组 - 有序元组

[英]Inherit Tuple in python - ordered tuple

I want to create a class that:我想创建一个类:

  • Has the same behavior as a tuple :具有与tuple相同的行为:
    • Immutable elements不可变元素
    • Has methods __len__ , index , __getitem__ and so on有方法__len__index__getitem__等等
  • The tuple has only floats and it's ordered元组只有floats并且是有序的
  • Has a property qtmin that counts how many elements are equal to the minimal有一个属性qtmin计算有多少元素等于最小值

So, my idea is to inherit from tuple 's class.所以,我的想法是继承tuple的类。

class MyTuple(tuple):
    @staticmethod
    def VerifyIsOrdered(U: tuple[float]):
        n = len(U)
        for i in range(n-1):
            if U[i] > U[i+1]:
                raise ValueError("U must be ordered")

    def __init__(self, U: tuple[float]):
        MyTuple.VerifyIsOrdered(U)
        super().__init__(U)

    @property
    def qtmin(self):
        minU = min(self)
        for i in range(len(self)):
            if self[i] != minU:
                return i
    
MyTuple([0, 1, 2, 3])  # qtmin = 1
MyTuple([0, 0, 0, 1, 2, 3])  # qtmin = 3

But I receive the error below at the line super().__init__(U)但是我在super().__init__(U)行收到以下错误

TypeError: object.__init__() takes exactly one argument (the instance to initialize)

But I don't get what's the problem, cause when I call super it's meant to initialize the original tuple .但我不明白有什么问题,因为当我调用super时,它意味着初始化原始tuple How can I solve it?我该如何解决?

tuple is immutable, so you need to use __new__ instead of __init__ . tuple是不可变的,因此您需要使用__new__而不是__init__ From the docs文档

new () is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. new () 主要是为了允许不可变类型(如 int、str 或 tuple)的子类自定义实例创建。 It is also commonly overridden in custom metaclasses in order to customize class creation.它也通常在自定义元类中被覆盖,以自定义类创建。

def __new__(cls, U: tuple[float]):
    MyTuple.VerifyIsOrdered(U)
    return super(MyTuple, cls).__new__(cls, tuple(U))

for better syntax, you can use unpacking like this:为了获得更好的语法,您可以像这样使用解包:

def __new__(cls,*U):
        MyTuple.VerifyIsOrdered(U)
        return super(MyTuple,cls).__new__(cls,U)

so you can write:所以你可以写:

MyTuple(0, 1, 2, 3)

instead of代替

MyTuple([0, 1, 2, 3])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM