将元组作为列表继承

时间:2013-10-28 14:25:35

标签: python list tuples

我刚刚编写了一个程序,其中有一个继承自tuple的类。但是,当我将参数作为列表传递时,它仍然有效。以下是我的一些代码:

class Board(tuple):    
    def __init__(self, tup):
        print(type(tup))
        super().__init__()

board = Board([[Cell(False) for i in range(10)] for j in range(10)])
print(type(board))

然后该程序输出:

<class 'list'>
<class '__main__.Board'>

我的问题如下:为什么当我说我会传递list时,Python让我传递tuple作为参数?

6 个答案:

答案 0 :(得分:5)

def __init__(self, tup):

就像其他功能一样。您已经传递了tup参数的列表。 你无法在python中限制参数的类型。子类化tuple只是意味着你继承了tuple的属性,而不是它只能接受元组作为参数。

编辑:如果你真的想要一种确保只接受元组的方法,那就出于某种原因。你可以像这样提出异常

class Board(tuple):
    def __init__(self, tup):
        if not isinstance(tup, tuple):
            raise TypeError("Constrcutor argument to Board should be a tuple")
        super().__init__()

print Board([1, 2])

<强>输出

TypeError: Constrcutor argument to Board should be a tuple

tuplelist

之间的效果比较
class Board(tuple):
    def __init__(self, tup):
        for i in tup:
            pass
myList, myTuple = range(10), tuple(xrange(10))

from timeit import timeit
print timeit("Board(myList)", "from __main__ import myList, Board", number = 1000000)
print timeit("Board(myTuple)", "from __main__ import myTuple, Board", number = 1000000)

<强>输出

0.44806599617
0.413192987442

这清楚地表明,将list作为参数传递的速度比tuple略慢,几乎可以忽略不计,而且它们的性能几乎相等。

答案 1 :(得分:1)

你没有说任何你希望tup成为元组的地方。您显式传入了一个列表,并且Python中的参数未经过类型检查。你可以像这样限制参数的类型:

if type(tup) is not type(()):
    raise ValueError('Expected a tuple')

然而,这并非真的有必要。做这样的事情的Pythonic方法不是关心你拥有的对象的类型,而是它是否支持你想要执行的操作。

答案 2 :(得分:1)

tuple描述了董事会本身的内容,而不是传递给初始化程序的任何参数的内容。

初始化程序的参数不一定代表对象本身;它们可能是新对象的参数之类的东西。鉴于你的函数实际上没有对输入做任何事情,你可以传递任何字面意思。

答案 3 :(得分:0)

列表和元组通常可互换地用作序列。

如果您尝试将其用作哈希值,则列表和元组之间的区别变得很重要:

class Board(tuple):    
    def __init__(self, tup):
        print(type(tup))
        d={}
        d[tup]='test'          # this will fail with an unhashable type, like a list
        super().__init__()

b1=Board(tuple([1,2,3]))
b2=Board([1,2,3])

打印:

<class 'tuple'>
<class 'list'>
Traceback (most recent call last):
  File "Untitled 8.py", line 9, in <module>
    b2=Board([1,2,3])
  File "Untitled 8.py", line 5, in __init__
    d[tup]='test'
TypeError: unhashable type: 'list'

Python中通常没有类型检查。它是一种EAFP语言。

如果您想要更“正式”的区分并对类型的子类化进行正式检查,请考虑使用collections.abc而不是基类型。

答案 4 :(得分:0)

如果您只想tuple作为__init__的参数,则可以执行以下操作:

class Board(tuple):    
    def __init__(self, tup):
        if not isinstance(tup, tuple):
            raise Exception('Invalid type')
        super().__init__()

但它真的糟糕的主意。它不是蟒蛇方式。

答案 5 :(得分:-1)

您的代码基本上是这样做的。

>>> tuple([1,2,3])  # tuple() takes a list
(1, 2, 3)           # turns it into a tuple

tuple进行子类化并不会将class'es参数限制为tuple;它只包含与tuple个实例相同的方法。